void tracePrintNewline(void) { if (!isTraced()) return; fprintf(stderr,"\n"); }
static void tracePrintFmtVa(const char * szFormat, va_list va) { if (!isTraced()) return; vfprintf(stderr,szFormat,va); }
void tracePrintPrefix(const char * szFunction) { if (!isTraced()) return; debugIndent(); fprintf(stderr,"[%s][at %lu] ",szFunction,getInputLineNumber()); }
void tracePrint(const char * szFunction, const char * szFormat,...) { if (!isTraced()) return; tracePrintPrefix(szFormat); va_list va; va_start(va,szFormat); tracePrintFmtVa (szFormat,va); va_end(va); tracePrintNewline(); }
void traceLeave(const char * szFunction,const char * szFormat,...) { if (!isTraced()) return; debugDec(); debugIndent (); fprintf(stderr,"[<< %s][at %lu] ",szFunction,getInputLineNumber()); va_list va; va_start(va,szFormat); vfprintf(stderr,szFormat,va); va_end(va); fprintf(stderr,"\n"); }
void parent() { int status; if (conf.xml) { printToplevelOpen(); printProcessTag(conf.command, conf.binArgc, conf.args); printTraceOpen(); } else { printPlHeader(conf.command, conf.binArgc, conf.args); } while (1) { /* Wait for child status to change: */ wait(&status); if (WIFEXITED(status)) { //exit(0); break; } if (WIFSIGNALED(status)) { //exit(0); break; } if (!WIFSTOPPED(status)) { //exit(0); break; } if (WSTOPSIG(status) == SIGTRAP) { /* Note that there are *three* reasons why the child might stop * with SIGTRAP: * 1) syscall entry * 2) syscall exit * 3) child calls exec */ struct user_regs_struct regs; ptrace(PTRACE_GETREGS, child_pid, 0, ®s); long syscall = regs.orig_rax; if (isTraced(syscall)) { handleSyscall(regs); } } else { // printf("Child stopped due to signal %d\n", WSTOPSIG(status)); //printf("| N/A | Signal %2d |\n", WSTOPSIG(status)); } fflush(stdout); /* Resume child, requesting that it stops again on syscall enter/exit * (in addition to any other reason why it might stop): */ ptrace(PTRACE_SYSCALL, child_pid, NULL, NULL); } if (conf.xml) { printTraceClose(); printToplevelClose(); } }