3 This file is part of gldbg
4 Copyright © 2009 Mikko Rasa, Mikkosoft Productions
5 Distributed under the GPL
11 #include <sys/ptrace.h>
13 #include <msp/core/except.h>
19 Process::Process(const vector<string> &a):
25 void Process::setenv(const string &key, const string &value)
30 void Process::launch()
33 throw InvalidState("Program is already running");
38 for(map<string, string>::const_iterator i=env.begin(); i!=env.end(); ++i)
39 ::setenv(i->first.c_str(), i->second.c_str(), true);
40 std::vector<char *> argv(args.size()+1);
41 for(unsigned i=0; i<args.size(); ++i)
42 argv[i] = strdup(args[i].c_str());
43 argv[args.size()] = 0;
44 ::ptrace(PTRACE_TRACEME, 0, 0, 0);
45 execvp(argv[0], &argv[0]);
51 throw SystemError("Could not launch process", errno);
57 int ret = waitpid(pid, &status, WNOHANG);
62 int code = WEXITSTATUS(status);
66 else if(WIFSIGNALED(status))
69 return 0x200|WTERMSIG(status);
71 else if(WIFSTOPPED(status))
73 int sig = WSTOPSIG(status);
74 if(sig==SIGTRAP && state==STARTING)
76 ptrace(PTRACE_CONT, 0, 0);
90 void Process::resume(int sig)
93 throw InvalidState("Program is not stopped");
94 ptrace(PTRACE_CONT, 0, (void *)sig);
101 throw InvalidState("Program is not running");
102 ptrace(PTRACE_KILL, 0, 0);
105 long Process::ptrace(int req, void *addr, void *data)
107 int ret = ::ptrace((__ptrace_request)req, pid, addr, data);
108 if(ret==-1 && ((req!=PTRACE_PEEKTEXT && req!=PTRACE_PEEKDATA && req!=PTRACE_PEEKUSER) || errno))
109 throw SystemError("ptrace error", errno);