[RFC] Add possibility to stop at thread events

Pierre Muller muller@ics.u-strasbg.fr
Wed Sep 2 15:43:00 GMT 2009


  The patch below adds the possibility to stop
the debuggee each time a thread is created or exited.
  The implementation is simple, it just adds two new
TARGET_WAITKIND_XXX enum values.
  The only problem is that it requires each target
to report this new status->kind, which is only done for
windows in that patch.
  The default behavior of GDB is unchanged as
it only stops if the new variable stop_on_thread_events
is set to a non-zero value (I took a integer value
by analogy with stop_on_solib_events, despite the fact
that a Boolean would probably make sense here...).
  Targets that leave up to GDB to add new threads
in handle_inferior_event functions would also 
stop at thread creation, but not on thread exit.
I have no idea about which targets are concerned by this.

  Comments welcome,


Pierre Muller
Pascal language support maintainer for GDB


2009-09-02  Pierre Muller  <muller@ics.u-strasbg.fr>

	* target.h (enum target_waitkind): Add TARGET_WAITKIND_CREATE_THREAD
	and TARGET_WAITKIND_EXIT_THREAD.
	* target.c (target_waitstatus_to_string): Adapt to new enum values.
	* infrun.c (stop_on_thread_events): New static variable.
	(show_stop_on_thread_events):  New function.
	(handle_inferior_event): Handle new enums and stop_on_thread_events
	variable. 
	(_initialize_target): Add set/show command for stop_on_thread_events
	variable.
	* windows-nat.c (get_windows_debug_event): Set ourstatus->kind to
new
	enum values when appropriate.

Index: src/gdb/infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.407
diff -u -p -r1.407 infrun.c
--- src/gdb/infrun.c	21 Aug 2009 18:54:44 -0000	1.407
+++ src/gdb/infrun.c	2 Sep 2009 12:31:00 -0000
@@ -224,6 +224,8 @@ static struct symbol *step_start_functio
 /* Nonzero if we want to give control to the user when we're notified
    of shared library events by the dynamic linker.  */
 static int stop_on_solib_events;
+static int stop_on_thread_events;
+
 static void
 show_stop_on_solib_events (struct ui_file *file, int from_tty,
 			   struct cmd_list_element *c, const char *value)
@@ -232,6 +234,14 @@ show_stop_on_solib_events (struct ui_fil
 		    value);
 }
 
+static void
+show_stop_on_thread_events (struct ui_file *file, int from_tty,
+			 struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Stopping for new thread events is %s.\n"),
+		    value);
+}
+
 /* Nonzero means expecting a trace trap
    and should stop the inferior and return silently when it happens.  */
 
@@ -2743,7 +2753,9 @@ handle_inferior_event (struct execution_
       return;
     }
 
-  if (ecs->new_thread_event)
+  if (ecs->new_thread_event
+      || ecs->ws.kind == TARGET_WAITKIND_CREATE_THREAD
+      || ecs->ws.kind == TARGET_WAITKIND_EXIT_THREAD)
     {
       if (non_stop)
 	/* Non-stop assumes that the target handles adding new threads
@@ -2761,6 +2773,13 @@ targets should add new threads to the th
 
       if (!ptid_equal (ecs->ptid, inferior_ptid))
 	context_switch (ecs->ptid);
+
+      if (stop_on_thread_events)
+	{
+	  stop_stepping (ecs);
+	  return;
+	}
+
       target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
@@ -5945,6 +5964,17 @@ to the user would be loading/unloading o
 			    show_stop_on_solib_events,
 			    &setlist, &showlist);
 
+  add_setshow_zinteger_cmd ("stop-on-thread-events", class_support,
+			    &stop_on_thread_events, _("\
+Set stopping for thread events."), _("\
+Show stopping for thread events."), _("\
+If nonzero, gdb will give control to the user when the operating system\n\
+notifies gdb of a created or exited thread."),
+			    NULL,
+			    show_stop_on_thread_events,
+			    &setlist, &showlist);
+
+
   add_setshow_enum_cmd ("follow-fork-mode", class_run,
 			follow_fork_mode_kind_names,
 			&follow_fork_mode_string, _("\
Index: src/gdb/target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.222
diff -u -p -r1.222 target.c
--- src/gdb/target.c	31 Aug 2009 20:18:45 -0000	1.222
+++ src/gdb/target.c	2 Sep 2009 12:31:01 -0000
@@ -2874,6 +2874,10 @@ target_waitstatus_to_string (const struc
       return xstrprintf ("%signore", kind_str);
     case TARGET_WAITKIND_NO_HISTORY:
       return xstrprintf ("%sno-history", kind_str);
+    case TARGET_WAITKIND_CREATE_THREAD:
+      return xstrprintf ("%screate-thread", kind_str);
+    case TARGET_WAITKIND_EXIT_THREAD:
+      return xstrprintf ("%sexit-thread", kind_str);
     default:
       return xstrprintf ("%sunknown???", kind_str);
     }
Index: src/gdb/target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.163
diff -u -p -r1.163 target.h
--- src/gdb/target.h	31 Aug 2009 20:18:45 -0000	1.163
+++ src/gdb/target.h	2 Sep 2009 12:31:01 -0000
@@ -135,7 +135,14 @@ enum target_waitkind
 
     /* The target has run out of history information,
        and cannot run backward any further.  */
-    TARGET_WAITKIND_NO_HISTORY
+    TARGET_WAITKIND_NO_HISTORY,
+
+    /* A new thread was registered.  */
+    TARGET_WAITKIND_CREATE_THREAD,
+
+    /* A thread was exited.  */
+    TARGET_WAITKIND_EXIT_THREAD,
+
   };
 
 struct target_waitstatus
Index: src/gdb/windows-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/windows-nat.c,v
retrieving revision 1.196
diff -u -p -r1.196 windows-nat.c
--- src/gdb/windows-nat.c	2 Jul 2009 17:21:07 -0000	1.196
+++ src/gdb/windows-nat.c	2 Sep 2009 12:31:05 -0000
@@ -57,6 +57,7 @@
 #include "solist.h"
 #include "solib.h"
 #include "xml-support.h"
+#include "target.h"
 
 #include "i386-tdep.h"
 #include "i387-tdep.h"
@@ -1358,6 +1359,7 @@ get_windows_debug_event (struct target_o
       th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
 					 current_event.dwThreadId),
 			     current_event.u.CreateThread.hThread);
+      ourstatus->kind = TARGET_WAITKIND_CREATE_THREAD;
       break;
 
     case EXIT_THREAD_DEBUG_EVENT:
@@ -1371,6 +1373,7 @@ get_windows_debug_event (struct target_o
 					   current_event.dwThreadId));
 	  th = &dummy_thread_info;
 	}
+      ourstatus->kind = TARGET_WAITKIND_EXIT_THREAD;
       break;
 
     case CREATE_PROCESS_DEBUG_EVENT:



More information about the Gdb-patches mailing list