X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgldbg.cpp;h=4bc169fcd0079abb2f99811a87db777266e4e86f;hb=efd709c6cdac15b7823e80ed64e448003aea835d;hp=001742d39599b85942702f797d8e8ed383d7a16d;hpb=6d297b506314c07bff3d77c2853a5f59380cfcb0;p=gldbg.git diff --git a/source/gldbg.cpp b/source/gldbg.cpp index 001742d..4bc169f 100644 --- a/source/gldbg.cpp +++ b/source/gldbg.cpp @@ -1,31 +1,23 @@ -/* $Id$ - -This file is part of gldbg -Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions -Distributed under the GPL -*/ - #include +#include #include +#include #include #include +#include #include #include #include -#include -#include -#include -#include #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::reg; +GlDbg *GlDbg::instance = 0; GlDbg::GlDbg(int argc, char **argv): cmd_interp(*this), @@ -36,8 +28,13 @@ GlDbg::GlDbg(int argc, char **argv): 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 &factories = Tool::get_factories(); for(list::const_iterator i=factories.begin(); i!=factories.end(); ++i) @@ -52,15 +49,15 @@ GlDbg::~GlDbg() 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; } @@ -68,7 +65,7 @@ int GlDbg::main() 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); @@ -77,18 +74,33 @@ void GlDbg::launch() 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]); - breakpoints.clear(); + for(BreakList::iterator i=breakpoints.begin(); i!=breakpoints.end(); ) + { + if(i->has_owner(0)) + { + i->owners.clear(); + i->owners.push_back(0); + send_breakpoint(i->function, i->flag, 0); + ++i; + } + else + breakpoints.erase(i++); + } + for(ToolList::iterator i=tools.begin(); i!=tools.end(); ++i) (*i)->process_started(); } void GlDbg::send(GlPacket *pkt) { + if(process.get_state()==Process::INACTIVE) + throw runtime_error("Program is not running"); + packet_send(pkt, sock_fd); } @@ -98,6 +110,15 @@ void GlDbg::hold() send(pkt); } +void GlDbg::send_breakpoint(unsigned short func, unsigned char set_flags, unsigned char clear_flags) +{ + GlPacket *pkt = packet_begin(FUNC_GLDBREAK); + packet_write_short(pkt, func); + packet_write_char(pkt, set_flags); + packet_write_char(pkt, clear_flags); + send(pkt); +} + void GlDbg::set_breakpoint(unsigned short func, unsigned char flag, Tool *owner) { Breakpoint *bp = (func ? get_breakpoint(func, flag) : 0); @@ -111,11 +132,8 @@ void GlDbg::set_breakpoint(unsigned short func, unsigned char flag, Tool *owner) breakpoints.back().add_owner(owner); } - GlPacket *pkt = packet_begin(FUNC_GLDBREAK); - packet_write_short(pkt, func); - packet_write_char(pkt, flag); - packet_write_char(pkt, 0); - send(pkt); + if(process.get_state()>=Process::RUNNING) + send_breakpoint(func, flag, 0); } } @@ -138,11 +156,8 @@ void GlDbg::clear_breakpoint(unsigned short func, unsigned char flag, Tool *owne break; } - GlPacket *pkt = packet_begin(FUNC_GLDBREAK); - packet_write_short(pkt, func); - packet_write_char(pkt, 0); - packet_write_char(pkt, flag); - send(pkt); + if(process.get_state()>=Process::RUNNING) + send_breakpoint(func, 0, flag); } } } @@ -163,7 +178,7 @@ void GlDbg::resume_from_break(Tool *tool) 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); } @@ -185,13 +200,13 @@ void GlDbg::tick() 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; } @@ -203,9 +218,9 @@ void GlDbg::tick() { 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); } @@ -250,7 +265,7 @@ void GlDbg::read_stream() } 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) @@ -291,7 +306,7 @@ GlDbg::Breakpoint *GlDbg::get_breakpoint(unsigned short func, unsigned char flag void GlDbg::sighandler(int sig) { if(sig==SIGCHLD) - got_sigchld = true; + instance->got_sigchld = true; }