This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFC] Add possibility to stop at thread events
- From: "Pierre Muller" <muller at ics dot u-strasbg dot fr>
- To: <gdb-patches at sourceware dot org>
- Date: Wed, 2 Sep 2009 17:42:20 +0200
- Subject: [RFC] Add possibility to stop at thread events
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: