6 #include <sys/ptrace.h>
13 Process::Process(const vector<string> &a):
19 void Process::setenv(const string &key, const string &value)
24 void Process::launch()
27 throw logic_error("Program is already running");
32 for(map<string, string>::const_iterator i=env.begin(); i!=env.end(); ++i)
33 ::setenv(i->first.c_str(), i->second.c_str(), true);
34 std::vector<char *> argv(args.size()+1);
35 for(unsigned i=0; i<args.size(); ++i)
36 argv[i] = strdup(args[i].c_str());
37 argv[args.size()] = 0;
38 ::ptrace(PTRACE_TRACEME, 0, 0, 0);
39 execvp(argv[0], &argv[0]);
45 throw runtime_error(strformat("Could not launch process: %s", strerror(errno)));
51 int ret = waitpid(pid, &status, WNOHANG);
56 int code = WEXITSTATUS(status);
60 else if(WIFSIGNALED(status))
63 return 0x200|WTERMSIG(status);
65 else if(WIFSTOPPED(status))
67 int sig = WSTOPSIG(status);
68 if(sig==SIGTRAP && state==STARTING)
70 ptrace(PTRACE_CONT, 0, 0);
84 void Process::resume(int sig)
87 throw logic_error("Program is not stopped");
88 ptrace(PTRACE_CONT, 0, (void *)sig);
95 throw logic_error("Program is not running");
96 ptrace(PTRACE_KILL, 0, 0);
97 // Make the debugger wait() for us
101 long Process::ptrace(int req, void *addr, void *data)
103 int ret = ::ptrace((__ptrace_request)req, pid, addr, data);
104 if(ret==-1 && ((req!=PTRACE_PEEKTEXT && req!=PTRACE_PEEKDATA && req!=PTRACE_PEEKUSER) || errno))
105 throw runtime_error(strformat("ptrace error: %s", strerror(errno)));