From 574d5a2c4f07bed91d9682e4f48e655e88e37498 Mon Sep 17 00:00:00 2001 From: Malfurious Date: Mon, 9 Oct 2023 16:31:56 -0400 Subject: Implement support for PTRACE_EVENT_FORK and ui Signed-off-by: Malfurious --- debugger.c | 18 ++++++++++ helpers.c | 1 + misplays.c | 115 +++++++++++++++++++++++++++++++------------------------------ 3 files changed, 78 insertions(+), 56 deletions(-) diff --git a/debugger.c b/debugger.c index 18f91e1..9a4d142 100644 --- a/debugger.c +++ b/debugger.c @@ -15,6 +15,7 @@ static const int PTRACE_OPTIONS = PTRACE_O_TRACECLONE | + PTRACE_O_TRACEFORK | PTRACE_O_TRACEEXEC | PTRACE_O_TRACEEXIT | PTRACE_O_TRACESYSGOOD; @@ -311,6 +312,7 @@ static int wait_thread(struct thread *th) { strcpy(th->status, "TERMINATED"); return 1; } else if (WIFSTOPPED(status)) { + struct process *eventproc; struct thread *eventth; unsigned long eventmsg; ptrace(PTRACE_GETEVENTMSG, th->id, NULL, &eventmsg); @@ -331,6 +333,22 @@ static int wait_thread(struct thread *th) { th->state = NULL; return 1; + case SIGTRAP | (PTRACE_EVENT_FORK << 8): + eventproc = new_process(eventmsg, th->proc->child); + eventth = new_thread(eventproc, eventmsg); + list_insert(eventproc->threads.end, eventth); + list_insert(th->proc->next, eventproc); + //while (!wait_thread(eventth)) {} + dbg_sync(eventproc); + + th->stopped = 1; + th->signal = 0; + th->doing = 0; + th->donext = 0; + strcpy(th->status, "FORK"); + th->state = NULL; + return 1; + case SIGTRAP | (PTRACE_EVENT_EXEC << 8): eventth = thread_by_id(th->proc, eventmsg); if (eventth->id != th->id) { diff --git a/helpers.c b/helpers.c index 163cd2e..9973093 100644 --- a/helpers.c +++ b/helpers.c @@ -33,6 +33,7 @@ void cursinit(void) { init_pair(1, COLOR_GREEN, -1); init_pair(2, COLOR_CYAN, -1); init_pair(3, COLOR_RED, -1); + init_pair(4, COLOR_YELLOW, -1); } void cursupdate(void) { diff --git a/misplays.c b/misplays.c index cda2abb..1ccf3d3 100644 --- a/misplays.c +++ b/misplays.c @@ -160,9 +160,17 @@ static void layout(struct list *processes, struct thread *th) { reset_panel(right, LINES-2, COLS-w, 1, w); clear(); - attron(COLOR_PAIR(1)); for (struct process *proc = processes->head; proc != processes->end; proc = proc->next) { + if (th->proc == proc) { + attron(COLOR_PAIR(1)); + printw("{ "); + } else { + attron(COLOR_PAIR(4)); + printw("{ "); + attroff(COLOR_PAIR(4)); + } + struct list *threads = &proc->threads; for (struct thread *t = threads->head; t != threads->end; t = t->next) { if (t == th) { @@ -172,11 +180,22 @@ static void layout(struct list *processes, struct thread *th) { if (t == th) { printw("**"); } - printw(" "); + + if (t->next != threads->end) { + printw(" "); + } } - } - attroff(COLOR_PAIR(1)); + + if (th->proc == proc) { + printw(" } "); + attroff(COLOR_PAIR(1)); + } else { + attron(COLOR_PAIR(4)); + printw(" } "); + attroff(COLOR_PAIR(4)); + } + } } int main(int argc, char **argv) { @@ -276,18 +295,41 @@ int main(int argc, char **argv) { break; case 't': proc = th->proc; - do { - th = th->next; - } while (th == proc->threads.end); + th = th->next; + if (th == proc->threads.end) { + do { + proc = proc->next; + } while (proc == processes.end); + th = proc->threads.head; + } layout(&processes, th); break; case 'T': proc = th->proc; - do { - th = th->prev; - } while (th == proc->threads.end); + th = th->prev; + if (th == proc->threads.end) { + do { + proc = proc->prev; + } while (proc == processes.end); + th = proc->threads.tail; + } layout(&processes, th); - break; /* todo: next/prev process bindings */ + break; + case 'd': + proc = th->proc; + if (proc->child) { + break; + } + if (proc->prev == proc->next) { + break; + } + struct process *del = proc; + do { + proc = proc->next; + } while (proc == processes.end); + th = proc->threads.head; + dbg_detach(del); + break; case ':': mvprintw(LINES-1, 0, ":"); curs_set(TRUE); @@ -338,51 +380,12 @@ int main(int argc, char **argv) { } } - dbg_detach(th->proc); /* todo: detach all procs */ + for (struct process *p = processes.head; p != processes.end; p = p->next) { + struct process *del = p; + p = p->prev; + dbg_detach(del); + } + endwin(); return EXIT_SUCCESS; } - - - - - - - - - - - - - - -//#include -//#include -//#include -//#include -//#include -//#include - -// //case 'd': -// // if (dbg->stopped) { -// // while (dbg->breaks.head != dbg->breaks.end) { -// // struct breakpoint *b = dbg->breaks.head; -// // list_remove(b); -// // free(b); -// // } -// // } -// // break; -// //case 'D': -// // if (dbg->stopped) { -// // if (ptrace(PTRACE_DETACH, dbg->id, NULL, NULL) < 0) { -// // pprintw(right, "PTRACE_DETACH: %s\n", strerror(errno)); -// // } -// // struct tracee *rm = dbg; -// // do { -// // dbg = dbg->next; -// // } while (dbg == tracees.end); -// // list_remove(rm); -// // dbg_free(rm); -// // free(rm); -// // } -// // break; -- cgit v1.2.3