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;

Reply via email to