CFLAGS := -ggdb -Wall -Wextra
CXXFLAGS := $(CFLAGS)
-PACKAGES_gldbg := mspcore mspstrings mspio mspfs libpng12
+PACKAGES_gldbg := libpng12
FLAVOR_ROOT := flavors/$(FLAVOR)
VPATH := $(FLAVOR_ROOT)
source/packet.c \
source/tmpalloc.c
SOURCES_gldump := source/gldump.c
-SOURCES_gldbg := source/gldbg.cpp \
+SOURCES_gldbg := source/main.cpp \
+ source/gldbg.cpp \
source/commandinterpreter.cpp \
source/process.cpp \
+ source/strformat.cpp \
source/tool.cpp
SOURCES_tracer := source/tracer.cpp
SOURCES_profiler := source/profiler.cpp
DEPS_all := $(call deps,$(SOURCES_all) $(TEMPLATES))
$(OBJECTS_gldbg): CXXFLAGS += $(shell pkg-config --cflags $(PACKAGES_gldbg))
-gldbg: LIBS += $(shell pkg-config --libs $(PACKAGES_gldbg)) -lreadline
+gldbg: LIBS += $(shell pkg-config --libs $(PACKAGES_gldbg)) -lreadline -lrt
gldump gldbg: LIBS += ./libgldbg.a
glwrap.so: LDFLAGS += -s
glwrap.so: LIBS += -ldl
/* $Id$
This file is part of gldbg
-Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
-#include <msp/strings/formatter.h>
#include "arraysize.h"
#include "arraystate.h"
#include "bufferstate.h"
#include "enums.h"
+#include "strformat.h"
using namespace std;
-using namespace Msp;
BufferContent::BufferContent():
consistent(true),
if(!result.empty())
result += '_';
- result += format("%c%d%s", kind, i->size, type);
+ result += strformat("%c%d%s", kind, i->size, type);
}
return result;
if(content.stride)
{
const char *what = (content.arrays.front().kind==GL_ELEMENT_ARRAY_BUFFER ? "indices" : "vertices");
- return format("%s, %d %s (%d bytes), %s",
- content.describe(), size/content.stride, what, size, describe_enum(usage, ""));
+ return content.describe()+strformat(", %d %s (%d bytes), %s",
+ size/content.stride, what, size, describe_enum(usage, ""));
}
else
- return format("%d bytes, %s", size, describe_enum(usage, ""));
+ return strformat("%d bytes, %s", size, describe_enum(usage, ""));
}
/* $Id$
This file is part of gldbg
-Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
-#include <msp/core/except.h>
+#include <stdexcept>
#include "glstate.h"
using namespace std;
-using namespace Msp;
namespace {
{
TextureMap::const_iterator i = textures.find(id);
if(i==textures.end())
- throw KeyError("Unknown texture");
+ throw runtime_error("Unknown texture");
return i->second;
}
{
BufferMap::const_iterator i = buffers.find(id);
if(i==buffers.end())
- throw KeyError("Unknown buffer");
+ throw runtime_error("Unknown buffer");
return i->second;
}
else if(array==GL_TEXTURE_COORD_ARRAY)
return texcoord_arrays[client_active_tex];
else
- throw InvalidParameterValue("Invalid array");
+ throw logic_error("Invalid array");
}
const ArrayState &GlState::get_texture_coord_array(unsigned index) const
return i->second;
// XXX Return a dummy?
- throw KeyError("Unknown attribute array");
+ throw runtime_error("Unknown attribute array");
}
void GlState::set_current_texture(GLenum target, unsigned id)
/* $Id$
This file is part of gldbg
-Copyright © 2010 Mikko Rasa, Mikkosoft Productions
+Copyright © 2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
-#include <msp/io/print.h>
+#include <stdexcept>
+#include <cstdio>
+#include <cstdlib>
#include "enums.h"
#include "gldbg.h"
#include "inspector.h"
+#include "strformat.h"
using namespace std;
-using namespace Msp;
Inspector::Inspector(GlDbg &dbg)
{
const GlState &glstate = state;
if(args=="vertex")
{
- IO::print("Current vertex attributes:\n");
+ printf("Current vertex attributes:\n");
const Vector4 &color = glstate.get_color();
- IO::print(" Color: [%05.3f, %05.3f, %05.3f, %05.3f]\n", color.r, color.g, color.b, color.a);
+ printf(" Color: [%05.3f, %05.3f, %05.3f, %05.3f]\n", color.r, color.g, color.b, color.a);
for(unsigned i=0; i<8; ++i)
{
const Vector4 &texcoord = glstate.get_texcoord(i);
- IO::print(" TexCoord%d: [%05.3f, %05.3f, %05.3f, %05.3f]\n", i, texcoord.s, texcoord.t, texcoord.p, texcoord.q);
+ printf(" TexCoord%d: [%05.3f, %05.3f, %05.3f, %05.3f]\n", i, texcoord.s, texcoord.t, texcoord.p, texcoord.q);
}
const Vector3 &normal = glstate.get_normal();
- IO::print(" Normal: [%05.3f, %05.3f, %05.3f]\n", normal.x, normal.y, normal.z);
+ printf(" Normal: [%05.3f, %05.3f, %05.3f]\n", normal.x, normal.y, normal.z);
}
else if(args=="bind")
{
- IO::print("Current bindings:\n");
+ printf("Current bindings:\n");
for(unsigned i=0; i<8; ++i)
{
- IO::print(" Texture unit %d:\n", i);
+ printf(" Texture unit %d:\n", i);
const TexUnitState &unit = glstate.get_texture_unit(i);
- IO::print(" GL_TEXTURE_2D: %s\n", unit.describe_binding(GL_TEXTURE_2D));
- IO::print(" GL_TEXTURE_3D: %s\n", unit.describe_binding(GL_TEXTURE_3D));
+ string descr = unit.describe_binding(GL_TEXTURE_2D);
+ printf(" GL_TEXTURE_2D: %s\n", descr.c_str());
+ descr = unit.describe_binding(GL_TEXTURE_3D);
+ printf(" GL_TEXTURE_3D: %s\n", descr.c_str());
}
- IO::print(" Buffers:\n");
+ printf(" Buffers:\n");
const BufferState *buf = glstate.get_current_buffer(GL_ARRAY_BUFFER);
- IO::print(" GL_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0));
+ printf(" GL_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0));
buf = glstate.get_current_buffer(GL_ELEMENT_ARRAY_BUFFER);
- IO::print(" GL_ELEMENT_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0));
+ printf(" GL_ELEMENT_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0));
}
else
- throw InvalidParameterValue("Invalid or missing argument");
+ throw runtime_error("Invalid or missing argument");
}
void Inspector::cmd_texture(const string &args)
if(args.empty())
{
const map<unsigned, TextureState> &textures = state.get_textures();
- IO::print("%d texture objects:\n", textures.size());
+ printf("%d texture objects:\n", textures.size());
for(map<unsigned, TextureState>::const_iterator i = textures.begin(); i!=textures.end(); ++i)
{
const TextureState &tex = i->second;
- IO::print(" %d: %s, %d images\n", i->first, tex.describe(), tex.images.size());
+ string descr = tex.describe();
+ printf(" %d: %s, %d images\n", i->first, descr.c_str(), tex.images.size());
}
}
else
{
- unsigned id = lexical_cast<unsigned>(args);
+ char *end = 0;
+ unsigned id = strtoul(args.c_str(), &end, 0);
+ if(end && *end)
+ throw runtime_error("Invalid texture id");
+
const TextureState &tex = state.get_texture(id);
- IO::print("Texture object %d\n", id);
- IO::print(" Target: %s\n", describe_enum(tex.target, "TextureTarget"));
- IO::print(" Images:\n");
+ printf("Texture object %d\n", id);
+ printf(" Target: %s\n", describe_enum(tex.target, "TextureTarget"));
+ printf(" Images:\n");
for(unsigned i=0; i<tex.images.size(); ++i)
{
- const TexImageState &img = tex.images[i];
- IO::print(" Level %2d: %s\n", i, img.describe());
+ string descr = tex.images[i].describe();
+ printf(" Level %2d: %s\n", i, descr.c_str());
}
- IO::print(" Min. filter: %s\n", describe_enum(tex.min_filter, "TextureMinFilter"));
- IO::print(" Mag. filter: %s\n", describe_enum(tex.mag_filter, "TextureMagFilter"));
- IO::print(" Wrap modes: S=%s / T=%s / R=%s\n", describe_enum(tex.wrap_s, "TextureWrapMode"),
+ printf(" Min. filter: %s\n", describe_enum(tex.min_filter, "TextureMinFilter"));
+ printf(" Mag. filter: %s\n", describe_enum(tex.mag_filter, "TextureMagFilter"));
+ printf(" Wrap modes: S=%s / T=%s / R=%s\n", describe_enum(tex.wrap_s, "TextureWrapMode"),
describe_enum(tex.wrap_t, "TextureWrapMode"), describe_enum(tex.wrap_r, "TextureWrapMode"));
- IO::print(" Compare mode: %s\n", describe_enum(tex.compare_mode, ""));
- IO::print(" Compare func: %s\n", describe_enum(tex.compare_func, "DepthFunction"));
- IO::print(" Generate mipmap: %s\n", tex.generate_mipmap);
+ printf(" Compare mode: %s\n", describe_enum(tex.compare_mode, ""));
+ printf(" Compare func: %s\n", describe_enum(tex.compare_func, "DepthFunction"));
+ printf(" Generate mipmap: %s\n", (tex.generate_mipmap ? "true" : "false"));
}
}
if(args.empty())
{
const GlState::BufferMap &buffers = state.get_buffers();
- IO::print("%d buffers:\n", buffers.size());
+ printf("%d buffers:\n", buffers.size());
for(GlState::BufferMap::const_iterator i=buffers.begin(); i!=buffers.end(); ++i)
- IO::print(" %d: %s\n", i->first, i->second.describe());
+ {
+ string descr = i->second.describe();
+ printf(" %d: %s\n", i->first, descr.c_str());
+ }
}
else
{
- unsigned id = lexical_cast<unsigned>(args);
+ char *end = 0;
+ unsigned id = strtoul(args.c_str(), &end, 0);
+ if(end && *end)
+ throw runtime_error("Invalid buffer id");
+
const BufferState &buf = state.get_buffer(id);
- IO::print("Buffer %d:\n", id);
- IO::print(" Size: %d bytes\n", buf.size);
- IO::print(" Usage: %s\n", describe_enum(buf.usage, ""));
+ printf("Buffer %d:\n", id);
+ printf(" Size: %d bytes\n", buf.size);
+ printf(" Usage: %s\n", describe_enum(buf.usage, ""));
if(buf.content.arrays.size()==1 && buf.content.arrays.front().kind==GL_ELEMENT_ARRAY_BUFFER)
{
const BufferContent::Array &array = buf.content.arrays.front();
- IO::print(" Arrays:\n");
- IO::print(" 0: Element indices, 1 %s\n", describe_enum(array.type, "DataType"));
+ printf(" Arrays:\n");
+ printf(" 0: Element indices, 1 %s\n", describe_enum(array.type, "DataType"));
- IO::print(" Data:\n");
+ printf(" Data:\n");
unsigned width = 1+buf.content.stride*2;
- string fmt = format(" %%%du", width);
+ char fmt[6];
+ snprintf(fmt, sizeof(fmt), " %%%du", width);
unsigned n_elems = buf.size/buf.content.stride;
string line;
const char *ptr = buf.data;
line = " ";
if(array.type==GL_UNSIGNED_BYTE)
- line += format(fmt, *(reinterpret_cast<const unsigned char *>(ptr)+i));
+ line += strformat(fmt, *(reinterpret_cast<const unsigned char *>(ptr)+i));
else if(array.type==GL_UNSIGNED_SHORT)
- line += format(fmt, *(reinterpret_cast<const unsigned short *>(ptr)+i));
+ line += strformat(fmt, *(reinterpret_cast<const unsigned short *>(ptr)+i));
else if(array.type==GL_UNSIGNED_INT)
- line += format(fmt, *(reinterpret_cast<const unsigned *>(ptr)+i));
+ line += strformat(fmt, *(reinterpret_cast<const unsigned *>(ptr)+i));
if(line.size()+1+width>79)
{
- IO::print("%s\n", line);
+ printf("%s\n", line.c_str());
line.clear();
}
}
if(!line.empty())
- IO::print("%s\n", line);
+ printf("%s\n", line.c_str());
}
else if(buf.content.stride)
{
- IO::print(" Stride: %d bytes\n", buf.content.stride);
+ printf(" Stride: %d bytes\n", buf.content.stride);
- IO::print(" Arrays:\n");
+ printf(" Arrays:\n");
const vector<BufferContent::Array> &arrays = buf.content.arrays;
for(vector<BufferContent::Array>::const_iterator i=arrays.begin(); i!=arrays.end(); ++i)
{
if(i->kind)
- IO::print(" %2d: %s, %d %s\n", i->offset,
+ printf(" %2d: %s, %d %s\n", i->offset,
describe_enum(i->kind, ""), i->size, describe_enum(i->type, "DataType"));
else
- IO::print(" %2d: Attrib %d, %d %s\n", i->offset,
+ printf(" %2d: Attrib %d, %d %s\n", i->offset,
i->index, i->size, describe_enum(i->type, "DataType"));
}
- IO::print(" Data:\n");
+ printf(" Data:\n");
string header;
for(vector<BufferContent::Array>::const_iterator i=arrays.begin(); i!=arrays.end(); ++i)
{
else if(!i->kind)
{
if(i->size==1)
- label = format("A %d", i->index);
+ label = strformat("A %d", i->index);
else
- label = format("Attrib %d", i->index);
+ label = strformat("Attrib %d", i->index);
}
unsigned width = i->size;
header += label;
header.append((width-label.size()+1)/2, ' ');
}
- IO::print(" %s\n", header);
+ printf(" %s\n", header.c_str());
unsigned n_verts = buf.size/buf.content.stride;
for(unsigned i=0; i<n_verts; ++i)
for(unsigned k=0; k<j->size; ++k)
{
if(j->type==GL_FLOAT)
- line += format(" %5.2f", *(reinterpret_cast<const float *>(base)+k));
+ line += strformat(" %5.2f", *(reinterpret_cast<const float *>(base)+k));
else if(j->type==GL_UNSIGNED_BYTE)
- line += format(" %3u", *(reinterpret_cast<const unsigned char *>(base)+k));
+ line += strformat(" %3u", *(reinterpret_cast<const unsigned char *>(base)+k));
}
}
- IO::print("%3d:%s\n", i, line);
+ printf("%3d:%s\n", i, line.c_str());
}
}
}
/* $Id$
This file is part of gldbg
-Copyright © 2010 Mikko Rasa, Mikkosoft Productions
+Copyright © 2010-2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
-#include <msp/io/print.h>
-#include <msp/time/units.h>
-#include <msp/time/utils.h>
+#include <stdexcept>
+#include <cstdio>
+#include <ctime>
#include "gldbg.h"
#include "profiler.h"
using namespace std;
-using namespace Msp;
Profiler::Profiler(GlDbg &dbg):
decoder(gldecoder_new(this, 0)),
draw_calls = 0;
vertices = 0;
triangles = 0;
- start = Msp::Time::now();
+ start = get_time();
}
else if(args=="off")
enabled = false;
else
- throw InvalidParameterValue("Invalid argument");
+ throw runtime_error("Invalid argument");
}
void Profiler::glDrawArrays(void *user_data, GLenum mode, int, int count)
{
Profiler *self = reinterpret_cast<Profiler *>(user_data);
- IO::print("%d draw calls, %d vertices, %d triangles\n", self->draw_calls, self->vertices, self->triangles);
+ printf("%d draw calls, %d vertices, %d triangles\n", self->draw_calls, self->vertices, self->triangles);
self->draw_calls = 0;
self->vertices = 0;
self->triangles = 0;
++self->frames;
- Msp::Time::TimeStamp t = Msp::Time::now();
- Msp::Time::TimeDelta dt = t-self->start;
- if(dt>Msp::Time::sec)
+ Time t = get_time();
+ float dt = (t-self->start)/1e6;
+ if(dt>1)
{
- Msp::IO::print("%d frames in %s seconds\n", self->frames, dt);
+ printf("%d frames in %.2f seconds\n", self->frames, dt);
self->start = t;
self->frames = 0;
}
}
+
+Profiler::Time Profiler::get_time()
+{
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ return ts.tv_sec*1000000+ts.tv_nsec/1000;
+}
/* $Id$
This file is part of gldbg
-Copyright © 2010 Mikko Rasa, Mikkosoft Productions
+Copyright © 2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
#ifndef PROFILER_H_
#define PROFILER_H_
-#include <msp/time/timestamp.h>
#include "gldecoder.h"
#include "tool.h"
class Profiler: public RegisteredTool<Profiler>
{
private:
+ typedef unsigned Time;
+
GlDecoder *decoder;
bool enabled;
- Msp::Time::TimeStamp start;
+ Time start;
unsigned frames;
unsigned draw_calls;
unsigned vertices;
static void glDrawElements(void *, GLenum, int, GLenum, const void *);
static void glDrawRangeElements(void *, GLenum, unsigned, unsigned, int, GLenum, const void *);
static void glXSwapBuffers(void *, Display *, GLXDrawable);
+
+ static Time get_time();
};
#endif
/* $Id$
This file is part of gldbg
-Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
-#include <msp/strings/formatter.h>
#include "enums.h"
+#include "strformat.h"
#include "texturestate.h"
using namespace std;
-using namespace Msp;
TexImageState::TexImageState():
width(0),
string TexImageState::describe() const
{
- string descr = format("%d", width);
+ string descr = strformat("%d", width);
if(height)
{
- descr += format("x%d", height);
+ descr += strformat("x%d", height);
if(depth)
- descr += format("x%d", height);
+ descr += strformat("x%d", height);
}
- descr += format(", %s", describe_enum(internal_format, "PixelFormat"));
+ descr += strformat(", %s", describe_enum(internal_format, "PixelFormat"));
return descr;
}
if(images.empty())
descr += ", undefined";
else
- descr += format(", %s", images.front().describe());
+ descr += ", "+images.front().describe();
return descr;
}
{
if(const TextureState *tex = get_current_texture(target))
{
- string descr = format("%d ", tex->id);
+ string descr = strformat("%d ", tex->id);
if(tex->images.empty())
descr += "(undefined)";
else
- descr += format("(%s)", tex->images.front().describe());
+ descr += "("+tex->images.front().describe()+")";
return descr;
}
else
/* $Id$
This file is part of gldbg
-Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
+#include <stdexcept>
+#include <cstdlib>
#include <signal.h>
#include <readline/readline.h>
-#include <msp/core/except.h>
-#include <msp/io/print.h>
-#include <msp/strings/lexicalcast.h>
-#include <msp/strings/utils.h>
#include "breakpoint.h"
#include "commandinterpreter.h"
#include "enums.h"
#include "tracer.h"
using namespace std;
-using namespace Msp;
CommandInterpreter::CommandInterpreter(GlDbg &d):
gldbg(d)
string name = cmd.substr(0, space);
CommandMap::const_iterator i = commands.lower_bound(name);
if(i==commands.end() || i->first.compare(0, name.size(), name))
- throw KeyError("Unknown command", name);
+ throw runtime_error("Unknown command "+name);
if(i->first!=name)
{
CommandMap::const_iterator j = i;
if((++j)!=commands.end() && !j->first.compare(0, name.size(), name))
- throw KeyError("Ambiguous command", name);
+ throw runtime_error("Ambiguous command "+name);
}
string args;
{
for(CommandMap::const_iterator i=commands.begin(); i!=commands.end(); ++i)
if(!dynamic_cast<const CommandAlias *>(i->second))
- IO::print("%-10s : %s\n", i->first, i->second->get_description());
+ printf("%-10s : %s\n", i->first.c_str(), i->second->get_description().c_str());
}
else
{
CommandMap::const_iterator i = commands.find(args);
if(i==commands.end())
- throw KeyError("Unknown command", args);
+ throw runtime_error("Unknown command "+args);
const Command *cmd = i->second;
while(const CommandAlias *alias = dynamic_cast<const CommandAlias *>(cmd))
cmd = alias->get_target();
- IO::print("%s : %s\n", i->first, cmd->get_description());
+ printf("%s : %s\n", i->first.c_str(), cmd->get_description().c_str());
if(!cmd->get_help().empty())
- IO::print("\n%s", cmd->get_help());
+ printf("\n%s", cmd->get_help().c_str());
}
}
{
unsigned short func = get_function(args.c_str());
if(!func)
- throw InvalidParameterValue("Unknown function");
+ throw runtime_error("Unknown function");
gldbg.set_breakpoint(func, BREAK_CALL, 0);
}
{
unsigned short func = get_function(args.c_str());
if(!func)
- throw InvalidParameterValue("Unknown function");
+ throw runtime_error("Unknown function");
gldbg.clear_breakpoint(func, BREAK_CALL, 0);
}
void CommandInterpreter::cmd_continue(const string &)
{
- IO::print("Continuing.\n");
+ printf("Continuing.\n");
gldbg.get_process().resume();
}
sig = SIGSEGV;
else if(args=="TERM" || args=="SIGTERM")
sig = SIGTERM;
- else if(isnumrc(args))
- sig = lexical_cast<unsigned>(args);
else
- throw InvalidParameterValue("Invalid signal specification");
+ {
+ char *end;
+ sig = strtoul(args.c_str(), &end, 0);
+ if(end && *end)
+ throw runtime_error("Invalid signal specification");
+ }
gldbg.get_process().resume(sig);
}
{
if(gldbg.get_process().get_state()!=Process::INACTIVE)
{
- IO::print("Program is still running. Kill it?\n");
+ printf("Program is still running. Kill it?\n");
char *answer = readline("[y/n] ");
if(answer[0]=='y')
{
gldbg.quit(true);
}
else
- IO::print("Not confirmed.\n");
+ printf("Not confirmed.\n");
}
else
gldbg.quit(false);
/* $Id$
This file is part of gldbg
-Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
#include <algorithm>
+#include <stdexcept>
#include <cstdlib>
+#include <climits>
#include <fcntl.h>
#include <signal.h>
+#include <unistd.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <readline/readline.h>
-#include <msp/core/except.h>
-#include <msp/fs/dir.h>
-#include <msp/io/print.h>
-#include <msp/strings/lexicalcast.h>
#include "functions.h"
#include "gldbg.h"
#include "gldecoder.h"
#include "packet.h"
+#include "strformat.h"
#include "tool.h"
using namespace std;
-using namespace Msp;
-Application::RegApp<GlDbg> GlDbg::reg;
+GlDbg *GlDbg::instance = 0;
GlDbg::GlDbg(int argc, char **argv):
cmd_interp(*this),
stop_reason(0),
current_break(0)
{
- FS::Path libdir = FS::get_sys_lib_dir(argv[0], "gldbg");
- process.setenv("LD_PRELOAD", (libdir/"glwrap.so").str().c_str());
+ instance = this;
+
+ char buf[PATH_MAX];
+ unsigned len = readlink("/proc/self/exe", buf, sizeof(buf));
+ string exe(buf, len);
+ string::size_type slash = exe.rfind('/');
+ process.setenv("LD_PRELOAD", (exe.substr(0, slash+1)+"glwrap.so"));
const list<Tool::Factory *> &factories = Tool::get_factories();
for(list<Tool::Factory *>::const_iterator i=factories.begin(); i!=factories.end(); ++i)
int GlDbg::main()
{
- catch_signal(SIGINT);
- catch_signal(SIGCHLD);
- set_loop_mode(TICK_BUSY);
+ signal(SIGINT, &sighandler);
+ signal(SIGCHLD, &sighandler);
- IO::print("GLdbg 0.0\n");
- IO::print("Copyright © 2009-2010 Mikkosoft Productions\n");
- IO::print("Type \"help\" for a list of commands\n");
+ printf("GLdbg 0.0\n");
+ printf("Copyright © 2009-2010 Mikkosoft Productions\n");
+ printf("Type \"help\" for a list of commands\n");
- Application::main();
+ while(1)
+ tick();
return 0;
}
void GlDbg::launch()
{
if(process.get_state()!=Process::INACTIVE)
- throw InvalidState("Program is already running");
+ throw runtime_error("Program is already running");
int fds[2];
socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
int flags = fcntl(sock_fd, F_GETFD);
fcntl(sock_fd, F_SETFD, flags|FD_CLOEXEC);
- process.setenv("GLWRAP_FD", lexical_cast(fds[1]));
- process.setenv("GLWRAP_CTRL_FD", lexical_cast(fds[1]));
+ process.setenv("GLWRAP_FD", strformat("%d", fds[1]));
+ process.setenv("GLWRAP_CTRL_FD", strformat("%d", fds[1]));
process.launch();
close(fds[1]);
void GlDbg::quit(bool force)
{
if(!force && process.get_state()!=Process::INACTIVE)
- throw InvalidState("Program is still running");
+ throw runtime_error("Program is still running");
exit(0);
}
if(stop_reason)
{
if(stop_reason==0x100)
- IO::print("Target process exited normally\n");
+ printf("Target process exited normally\n");
else if((stop_reason>>8)==1)
- IO::print("Target process exited with status %d\n", stop_reason&0xFF);
+ printf("Target process exited with status %d\n", stop_reason&0xFF);
else if((stop_reason>>8)==2)
- IO::print("Target process terminated with signal %d\n", stop_reason&0xFF);
+ printf("Target process terminated with signal %d\n", stop_reason&0xFF);
else if((stop_reason>>8)==3)
- IO::print("Target process stopped by signal %d\n", stop_reason&0xFF);
+ printf("Target process stopped by signal %d\n", stop_reason&0xFF);
stop_reason = 0;
}
{
cmd_interp.execute(line);
}
- catch(const Exception &e)
+ catch(const exception &e)
{
- IO::print("%s\n", e.what());
+ printf("%s\n", e.what());
}
free(line);
}
}
if(announce)
- IO::print("Breakpoint: %s\n", get_function_name(func));
+ printf("Breakpoint: %s\n", get_function_name(func));
}
for(ToolList::iterator i=tools.begin(); i!=tools.end(); ++i)
void GlDbg::sighandler(int sig)
{
if(sig==SIGCHLD)
- got_sigchld = true;
+ instance->got_sigchld = true;
}
/* $Id$
This file is part of gldbg
-Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
#ifndef GLDBG_H_
#define GLDBG_H_
+#include <list>
#include <string>
#include <vector>
-#include <msp/core/application.h>
-#include <msp/fs/path.h>
#include "commandinterpreter.h"
#include "packet.h"
#include "process.h"
class Tool;
-class GlDbg: public Msp::Application
+class GlDbg
{
private:
typedef std::list<Tool *> ToolList;
const Breakpoint *current_break;
ToolList break_holders;
- static RegApp<GlDbg> reg;
+ static GlDbg *instance;
public:
GlDbg(int, char **);
void check_child();
void read_stream();
Breakpoint *get_breakpoint(unsigned short, unsigned char);
- virtual void sighandler(int);
+
+ static void sighandler(int);
};
#endif
*/
#include <algorithm>
+#include <stdexcept>
#include <png.h>
-#include <msp/io/print.h>
#include "arraysize.h"
#include "breakpoint.h"
#include "functions.h"
#include "gldbg.h"
#include "grabber.h"
+#include "strformat.h"
using namespace std;
-using namespace Msp;
Grabber::Grabber(GlDbg &g):
gldbg(g),
}
}
else
- throw InvalidParameterValue("Invalid autograb mode");
+ throw runtime_error("Invalid autograb mode");
}
void Grabber::grab()
{
Grabber *self = reinterpret_cast<Grabber *>(user_data);
- string fn = Msp::format("grab-%04d-%04d.png", self->frame_num, self->grab_num);
+ string fn = strformat("grab-%04d-%04d.png", self->frame_num, self->grab_num);
if(format==GL_RGBA && type==GL_UNSIGNED_BYTE)
{
if(self->write_png(fn, width, height, data)<0)
- IO::print("Failed to write png file %s\n", fn);
+ printf("Failed to write png file %s\n", fn.c_str());
else
- IO::print("Grabbed %dx%d png image to %s\n", width, height, fn);
+ printf("Grabbed %dx%d png image to %s\n", width, height, fn.c_str());
}
++self->grab_num;
--- /dev/null
+/* $Id$
+
+This file is part of gldbg
+Copyright © 2011 Mikko Rasa, Mikkosoft Productions
+Distributed under the GPL
+*/
+
+#include "gldbg.h"
+
+int main(int argc, char **argv)
+{
+ GlDbg gldbg(argc, argv);
+ return gldbg.main();
+}
/* $Id$
This file is part of gldbg
-Copyright © 2009 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009, 2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
+#include <stdexcept>
#include <cstdlib>
#include <cerrno>
#include <cstring>
#include <sys/ptrace.h>
#include <sys/wait.h>
-#include <msp/core/except.h>
#include "process.h"
+#include "strformat.h"
using namespace std;
-using namespace Msp;
Process::Process(const vector<string> &a):
args(a),
void Process::launch()
{
if(state!=INACTIVE)
- throw InvalidState("Program is already running");
+ throw logic_error("Program is already running");
pid = fork();
if(pid==0)
else if(pid>0)
state = STARTING;
else
- throw SystemError("Could not launch process", errno);
+ throw runtime_error(strformat("Could not launch process: %s", strerror(errno)));
}
int Process::check()
void Process::resume(int sig)
{
if(state!=STOPPED)
- throw InvalidState("Program is not stopped");
+ throw logic_error("Program is not stopped");
ptrace(PTRACE_CONT, 0, (void *)sig);
state = RUNNING;
}
void Process::kill()
{
if(state==INACTIVE)
- throw InvalidState("Program is not running");
+ throw logic_error("Program is not running");
ptrace(PTRACE_KILL, 0, 0);
// Make the debugger wait() for us
state = RUNNING;
{
int ret = ::ptrace((__ptrace_request)req, pid, addr, data);
if(ret==-1 && ((req!=PTRACE_PEEKTEXT && req!=PTRACE_PEEKDATA && req!=PTRACE_PEEKUSER) || errno))
- throw SystemError("ptrace error", errno);
+ throw runtime_error(strformat("ptrace error: %s", strerror(errno)));
return ret;
}
--- /dev/null
+/* $Id$
+
+This file is part of gldbg
+Copyright © 2011 Mikko Rasa, Mikkosoft Productions
+Distributed under the GPL
+*/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "strformat.h"
+
+using namespace std;
+
+string strformat(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char buf[2048];
+ vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+ return buf;
+}
--- /dev/null
+/* $Id$
+
+This file is part of gldbg
+Copyright © 2011 Mikko Rasa, Mikkosoft Productions
+Distributed under the GPL
+*/
+
+#ifndef STRFORMAT_H_
+#define STRFORMAT_H_
+
+#include <string>
+
+std::string strformat(const char *, ...);
+
+#endif
/* $Id$
This file is part of gldbg
-Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
-#include <msp/io/file.h>
-#include <msp/io/print.h>
+#include <stdexcept>
#include "gldbg.h"
#include "glprint.h"
#include "tracer.h"
using namespace std;
-using namespace Msp;
Tracer::Tracer(GlDbg &dbg):
glprint(new GlPrint(0, 16384)),
out(0),
- delete_out(true),
+ close_out(true),
enabled(true)
{
dbg.get_command_interpreter().register_command("trace", this, &Tracer::cmd_trace)
Tracer::~Tracer()
{
delete glprint;
- if(delete_out)
- delete out;
+ if(close_out && out)
+ fclose(out);
}
-void Tracer::set_output(IO::Base *o, bool d)
+void Tracer::set_output(FILE *o, bool d)
{
- if(delete_out)
- delete out;
+ if(close_out && out)
+ fclose(out);
out = o;
- delete_out = d;
+ close_out = d;
}
void Tracer::decode(const char *data, unsigned len)
{
const char *buf = glprint->get_buffer();
if(buf[0])
- IO::print(*out, "%s\n", buf);
+ fprintf(out, "%s\n", buf);
}
}
{
if(args.empty() || args=="-")
{
- set_output(&IO::cout, false);
- IO::print("Tracing to stdout\n");
+ set_output(stdout, false);
+ printf("Tracing to stdout\n");
}
else if(args=="on")
{
if(!out)
- throw InvalidState("Output is not set");
+ throw runtime_error("Output is not set");
enabled = true;
- IO::print("Tracing enabled\n");
+ printf("Tracing enabled\n");
}
else if(args=="off")
{
enabled = false;
- IO::print("Tracing disabled\n");
+ printf("Tracing disabled\n");
}
else if(args=="end")
{
set_output(0, true);
- IO::print("Tracing terminated\n");
+ printf("Tracing terminated\n");
}
else
{
- set_output(new IO::File(args, IO::M_WRITE), true);
- IO::print("Tracing to %s\n", args);
+ FILE *f = fopen(args.c_str(), "w");
+ if(!f)
+ throw runtime_error("Could not open trace file");
+
+ set_output(f, true);
+ printf("Tracing to %s\n", args.c_str());
}
}
/* $Id$
This file is part of gldbg
-Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions
+Copyright © 2009-2011 Mikko Rasa, Mikkosoft Productions
Distributed under the GPL
*/
#ifndef TRACER_H_
#define TRACER_H_
-#include <msp/io/base.h>
+#include <cstdio>
#include "tool.h"
struct GlPrint;
{
private:
GlPrint *glprint;
- Msp::IO::Base *out;
- bool delete_out;
+ FILE *out;
+ bool close_out;
bool enabled;
public:
virtual void decode(const char *, unsigned);
private:
- void set_output(Msp::IO::Base *, bool);
+ void set_output(FILE *, bool);
void cmd_trace(const std::string &);
};