diff options
Diffstat (limited to 'util/statetrace/tracechild.cc')
-rw-r--r-- | util/statetrace/tracechild.cc | 188 |
1 files changed, 88 insertions, 100 deletions
diff --git a/util/statetrace/tracechild.cc b/util/statetrace/tracechild.cc index 85f42addd..b5665ff37 100644 --- a/util/statetrace/tracechild.cc +++ b/util/statetrace/tracechild.cc @@ -37,123 +37,111 @@ using namespace std; -bool TraceChild::startTracing(const char * pathToFile, char * const argv[]) +bool +TraceChild::startTracing(const char * pathToFile, char * const argv[]) { - instructions = 0; - pid = fork(); - if(pid == -1) - { - cout << "fork failed" << endl; - return false; + instructions = 0; + pid = fork(); + if (pid == -1) { + cout << "fork failed" << endl; + return false; + } else if (pid == 0) { + //We're the child. Get things ready and then exec the program to trace. + //Let our parent trace us + if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) { + cout << "Failure calling TRACEME\n" << strerror(errno) << endl; + return false; } - else if(pid == 0) - { - //We're the child. Get things ready and then exec the - //program to trace. - //Let our parent trace us - if(ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) - { - cout << "Failure calling TRACEME\n"; - cout << strerror(errno) << endl; - return false; - } + //Set up an empty environment for the child... We would want to + //specify this somehow at some point + char * env[] = {NULL}; - //Set up an empty environment for the child... - //We would want to specify this somehow at some point - char * env[] = {NULL}; + //Start the program to trace + execve(pathToFile, argv, env); - //Start the program to trace - execve(pathToFile, argv, env); + //We should never get here, so this is an error! + cout << "Exec failed\n" << strerror(errno) << endl; + return false; + } - //We should never get here, so this is an error! - cout << "Exec failed\n"; - cout << strerror(errno) << endl; - return false; - } - - //From this point forward, we know we're in the parent process. - if(!doWait()) - { - cout << "Didn't wait successfully" << endl; - return false; - } - tracing = true; - return true; + //From this point forward, we know we're in the parent process. + if (!doWait()) { + cout << "Didn't wait successfully" << endl; + return false; + } + tracing = true; + return true; } -bool TraceChild::stopTracing() +bool +TraceChild::stopTracing() { - if(ptrace(PTRACE_KILL, pid, 0, 0) != 0) - return false; - tracing = false; - return true; + if (ptrace(PTRACE_KILL, pid, 0, 0) != 0) + return false; + tracing = false; + return true; } -bool TraceChild::step() +bool +TraceChild::step() { - ptraceSingleStep(); + ptraceSingleStep(); } -bool TraceChild::ptraceSingleStep() +bool +TraceChild::ptraceSingleStep() { - if(!tracing) - { - cout << "Not tracing!" << endl; - return false; - } - if(ptrace(PTRACE_SINGLESTEP, pid, 0, 0) != 0) - { - switch(errno) - { - case EBUSY: cout << "EBUSY" << endl; break; - case EFAULT: cout << "EFAULT" << endl; break; - case EIO: cout << "EIO" << endl; break; - case EPERM: cout << "EPERM" << endl; break; - case ESRCH: cout << "ESRCH" << endl; break; - default: cout << "Unknown error" << endl; break; - } - cout << "Not able to single step!" << endl; - tracing == false; - return false; + if (!tracing) { + cout << "Not tracing!" << endl; + return false; + } + if (ptrace(PTRACE_SINGLESTEP, pid, 0, 0) != 0) { + switch (errno) { + case EBUSY: cout << "EBUSY" << endl; break; + case EFAULT: cout << "EFAULT" << endl; break; + case EIO: cout << "EIO" << endl; break; + case EPERM: cout << "EPERM" << endl; break; + case ESRCH: cout << "ESRCH" << endl; break; + default: cout << "Unknown error" << endl; break; } - doWait(); - update(pid); + cout << "Not able to single step!" << endl; + tracing == false; + return false; + } + doWait(); + update(pid); } -bool TraceChild::doWait() +bool +TraceChild::doWait() { - int wait_val; - wait(&wait_val); - if(WIFEXITED(wait_val)) - { - cerr << "Program exited! Exit status is " - << WEXITSTATUS(wait_val) << endl; - cerr << "Executed " << instructions - << " instructions." << endl; - tracing = false; - return false; - } - if(WIFSIGNALED(wait_val)) - { - if(WTERMSIG(wait_val)) - cerr << "Program terminated by signal " - << WTERMSIG(wait_val) << endl; - if(WCOREDUMP(wait_val)) - cerr << "Program core dumped!" << endl; - tracing = false; - cerr << "Executed " << instructions - << " instructions." << endl; - return false; - } - if(WIFSTOPPED(wait_val) && WSTOPSIG(wait_val) != SIGTRAP) - { - cerr << "Program stopped by signal " - << WSTOPSIG(wait_val) << endl; - tracing = false; - cerr << "Executed " << instructions - << " instructions." << endl; - return false; - } - return true; + int wait_val; + wait(&wait_val); + if (WIFEXITED(wait_val)) { + cerr << "Program exited! Exit status is " + << WEXITSTATUS(wait_val) << endl; + cerr << "Executed " << instructions + << " instructions." << endl; + tracing = false; + return false; + } + if (WIFSIGNALED(wait_val)) { + if (WTERMSIG(wait_val)) + cerr << "Program terminated by signal " + << WTERMSIG(wait_val) << endl; + if (WCOREDUMP(wait_val)) + cerr << "Program core dumped!" << endl; + tracing = false; + cerr << "Executed " << instructions + << " instructions." << endl; + return false; + } + if (WIFSTOPPED(wait_val) && WSTOPSIG(wait_val) != SIGTRAP) { + cerr << "Program stopped by signal " << WSTOPSIG(wait_val) << endl; + tracing = false; + cerr << "Executed " << instructions << " instructions." << endl; + return false; + } + return true; } |