Hi, This is a patch to gdbstub that provides a "workaround" for the problem reported by Frank " gdbstub/uprobes problems: uprobe_unregister with halted target"
I also want to know if it's possible to have soft breakpoints (or traps) handled by gdb in multiple ways, i.e one from stub (using uprobes), the other from gdb itself(example handle)? I call this a workaround because this patch expects all SIGTRAPS to be handled by stub and need not be sent to gdb for processing. i.e (gdb) handle SIGTRAP may not work. However I dont think its wrong assumption to make because when gdb inserts a breakpoint when using a remote protocol and gdb stub uses uprobes then its better left to uprobes. In this case, when gdbstub hits a breakpoint, it should either be handled by uprobes or passed to the program. Please do let me know if this is a wrong assumption. -- Signed-Off-by: Srikar Dronamraju <sri...@linux.vnet.ibm.com> diff --git a/kernel/utrace-gdb.c b/kernel/utrace-gdb.c index edf2769..a11fa9a 100644 --- a/kernel/utrace-gdb.c +++ b/kernel/utrace-gdb.c @@ -341,6 +341,7 @@ u32 gdb_utrace_report_signal(u32 action, struct gdb_connection *p = engine->data; u32 ret = action; int kern_p; + unsigned int signo = map_signal_kern2gdb(info->si_signo); mutex_lock(&p->output_mutex); @@ -354,7 +355,9 @@ u32 gdb_utrace_report_signal(u32 action, * * 1) This is an ordinary signal. We UTRACE_STOP to notify gdb. * - * 2) This is a SIGTRAP arising from a breakpoint. We UTRACE_STOP. + * 2) This is a SIGTRAP arising from a breakpoint. + * If we have uprobes support: allow uprobes to handle it: UTRACE_RESUME. + * Else UTRACE_STOP. * * 3) This is a signal our code injected to stop the process, in lieu * of UTRACE_INTERRUPT. We UTRACE_STOP | UTRACE_SIGNAL_IGN. @@ -377,12 +380,18 @@ u32 gdb_utrace_report_signal(u32 action, ret = UTRACE_RESUME; /* deliver */ } else if (p->stop_signals > 0 /*&& kern_p*/) { /* Case 3 */ p->stop_signals --; - snprintf (p->stopcode, GDB_BUFMAX, "S%02x", map_signal_kern2gdb(info->si_signo)); + snprintf (p->stopcode, GDB_BUFMAX, "S%02x", signo); push_output_packet (p, p->stopcode); p->at_quiesce_do = UTRACE_STOP; ret = UTRACE_STOP | UTRACE_SIGNAL_IGN; - } else { /* Cases 1, 2 */ - snprintf (p->stopcode, GDB_BUFMAX, "S%02x", map_signal_kern2gdb(info->si_signo)); +#ifdef CONFIG_HAVE_UPROBES + } else if (info->si_signo == signo) { + p->skip_signals --; + p->at_quiesce_do = UTRACE_RESUME; + ret = UTRACE_RESUME; /* deliver */ +#endif /* CONFIG_HAVE_UPROBES */ + } else { /* Cases 1, 2 */ + snprintf (p->stopcode, GDB_BUFMAX, "S%02x", signo); push_output_packet (p, p->stopcode); p->at_quiesce_do = UTRACE_STOP; ret = UTRACE_STOP;