3 This file is part of gldbg
4 Copyright © 2009 Mikko Rasa, Mikkosoft Productions
5 Distributed under the GPL
12 #include <sys/socket.h>
13 #include <readline/readline.h>
14 #include <msp/core/except.h>
15 #include <msp/fs/dir.h>
16 #include <msp/io/print.h>
17 #include <msp/strings/lexicalcast.h>
24 Application::RegApp<GlDbg> GlDbg::reg;
26 GlDbg::GlDbg(int argc, char **argv):
28 process(vector<string>(argv+1, argv+argc)),
33 FS::Path libdir = FS::get_sys_lib_dir(argv[0], "gldbg");
34 process.setenv("LD_PRELOAD", (libdir/"glwrap.so").str().c_str());
40 catch_signal(SIGCHLD);
41 set_loop_mode(TICK_BUSY);
43 IO::print("GLdbg 0.0\n");
44 IO::print("Copyright © 2009 Mikkosoft Productions\n");
45 IO::print("Type \"help\" for a list of commands\n");
54 if(process.get_state()!=Process::INACTIVE)
55 throw InvalidState("Program is already running");
58 socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
61 int flags = fcntl(sock_fd, F_GETFD);
62 fcntl(sock_fd, F_SETFD, flags|FD_CLOEXEC);
64 process.setenv("GLWRAP_FD", lexical_cast(fds[1]));
69 void GlDbg::quit(bool force)
71 if(!force && process.get_state()!=Process::INACTIVE)
72 throw InvalidState("Program is still running");
81 int ret = process.check();
83 IO::print("Target process exited normally\n");
85 IO::print("Target process exited with status %d\n", ret&0xFF);
87 IO::print("Target process terminated with signal %d\n", ret&0xFF);
90 IO::print("Target process stopped by signal %d\n", ret&0xFF);
95 Process::State pstate = process.get_state();
96 if((pstate!=Process::INACTIVE && pstate!=Process::STOPPED) || flushing)
100 char *line = readline("gldbg> ");
105 cmd_interp.execute(line);
107 catch(const Exception &e)
109 IO::print("%s\n", e.what());
113 else if(pstate==Process::INACTIVE)
118 void GlDbg::read_stream()
120 pollfd pfd = { sock_fd, POLLIN, 0 };
121 int ret = poll(&pfd, 1, (flushing ? 0 : -1));
125 ret = read(sock_fd, rbuf, 1024);
128 buffer.append(rbuf, ret);
129 while(buffer.size()>buf_offset)
131 const char *data = buffer.data()+buf_offset;
132 unsigned len = buffer.size()-buf_offset;
133 int size = gldecoder_decode(0, data, len);
136 tracer.decode(data, len);
137 glstate.decode(data, len);
138 profiler.decode(data, len);
143 buffer.erase(0, buf_offset);
152 void GlDbg::sighandler(int sig)