This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFC][patch 9/9] export threads to Python
- From: Thiago Jung Bauermann <bauerman at br dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 29 Apr 2008 12:52:21 -0300
- Subject: [RFC][patch 9/9] export threads to Python
- References: <20080429155212.444237503@br.ibm.com>
2008-04-29 Tom Tromey <tromey@redhat.com>
* Makefile.in (python.o): Depend on inferior.h and gdbthread.h.
* gdbthread.h (prune_threads): Declare.
* python/python.c: Include inferior.h, gdbthread.h.
(demand_python): Register new functions.
(count_callback): New function.
(struct set_thread_info): New struct.
(update_tuple_callback): New function.
(gdbpy_get_threads): Likewise.
(gdbpy_get_current_thread): Likewise.
(gdbpy_switch_to_thread): Likewise.
* thread.c (prune_threads): No longer 'static'. Rewrote.
Index: python-tromey.git/gdb/Makefile.in
===================================================================
--- python-tromey.git.orig/gdb/Makefile.in 2008-04-29 11:49:51.000000000 -0300
+++ python-tromey.git/gdb/Makefile.in 2008-04-29 11:55:27.000000000 -0300
@@ -3426,7 +3426,7 @@ PYTHON_CFLAGS=-fno-strict-aliasing
python.o: $(srcdir)/python/python.c $(defs_h) $(python_h) \
$(command_h) $(libiberty_h) $(cli_decode_h) $(charset_h) $(top_h) \
$(exceptions_h) $(python_internal_h) $(version_h) $(solib_h) \
- $(linespec_h) $(symtab_h) $(source_h)
+ $(linespec_h) $(symtab_h) $(source_h) $(inferior_h) $(gdbthread_h)
$(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
python-block.o: $(srcdir)/python/block.c $(defs_h) $(block_h) $(dictionary_h) \
$(symtab_h) $(python_h) $(python_internal_h)
Index: python-tromey.git/gdb/gdbthread.h
===================================================================
--- python-tromey.git.orig/gdb/gdbthread.h 2008-04-29 11:47:48.000000000 -0300
+++ python-tromey.git/gdb/gdbthread.h 2008-04-29 11:54:06.000000000 -0300
@@ -110,6 +110,9 @@ extern int valid_thread_id (int thread);
/* Search function to lookup a thread by 'pid'. */
extern struct thread_info *find_thread_pid (ptid_t ptid);
+/* Prune dead threads from the list of threads. */
+extern void prune_threads (void);
+
/* Iterator function to call a user-provided callback function
once for each known thread. */
typedef int (*thread_callback_func) (struct thread_info *, void *);
Index: python-tromey.git/gdb/python/python.c
===================================================================
--- python-tromey.git.orig/gdb/python/python.c 2008-04-29 11:47:56.000000000 -0300
+++ python-tromey.git/gdb/python/python.c 2008-04-29 11:54:06.000000000 -0300
@@ -31,6 +31,8 @@
#include "symtab.h"
#include "source.h"
#include "version.h"
+#include "inferior.h"
+#include "gdbthread.h"
#include <ctype.h>
@@ -41,6 +43,9 @@ static PyObject *execute_gdb_command (Py
static PyObject *gdbpy_solib_address (PyObject *, PyObject *);
static PyObject *gdbpy_decode_line (PyObject *, PyObject *);
static PyObject *gdbpy_find_pc_function (PyObject *, PyObject *);
+static PyObject *gdbpy_get_threads (PyObject *, PyObject *);
+static PyObject *gdbpy_get_current_thread (PyObject *, PyObject *);
+static PyObject *gdbpy_switch_to_thread (PyObject *, PyObject *);
void
@@ -85,6 +90,13 @@ demand_python ()
Return a tuple holding the file name (or None) and line number (or None).\n\
Note: may later change to return an object." },
+ { "get_threads", gdbpy_get_threads, METH_NOARGS,
+ "Return a tuple holding all the valid thread IDs." },
+ { "get_current_thread", gdbpy_get_current_thread, METH_NOARGS,
+ "Return the thread ID of the current thread." },
+ { "switch_to_thread", gdbpy_switch_to_thread, METH_VARARGS,
+ "Switch to a thread, given the thread ID." },
+
{NULL, NULL, 0, NULL}
};
@@ -474,6 +486,75 @@ gdbpy_decode_line (PyObject *self, PyObj
+/* Threads. */
+
+static int
+count_callback (struct thread_info *info, void *user_data)
+{
+ int *count = (int *) user_data;
+ ++*count;
+ return 0;
+}
+
+struct set_thread_info
+{
+ PyObject *tuple;
+ int index;
+};
+
+static int
+update_tuple_callback (struct thread_info *info, void *user_data)
+{
+ struct set_thread_info *tinfo = (struct set_thread_info *) user_data;
+ PyTuple_SetItem (tinfo->tuple, tinfo->index, PyInt_FromLong (info->num));
+ ++tinfo->index;
+ return 0;
+}
+
+static PyObject *
+gdbpy_get_threads (PyObject *unused1, PyObject *unused2)
+{
+ int thread_count = 0;
+ struct set_thread_info info;
+ PyObject *result;
+
+ prune_threads ();
+ target_find_new_threads ();
+
+ iterate_over_threads (count_callback, &thread_count);
+
+ if (!thread_count)
+ Py_RETURN_NONE;
+
+ result = PyTuple_New (thread_count);
+ info.tuple = result;
+ info.index = 0;
+ iterate_over_threads (update_tuple_callback, &info);
+ return result;
+}
+
+static PyObject *
+gdbpy_get_current_thread (PyObject *unused1, PyObject *unused2)
+{
+ if (PIDGET (inferior_ptid) == 0)
+ Py_RETURN_NONE;
+ return PyInt_FromLong (pid_to_thread_id (inferior_ptid));
+}
+
+static PyObject *
+gdbpy_switch_to_thread (PyObject *self, PyObject *args)
+{
+ int id;
+ if (! PyArg_ParseTuple (args, "i", &id))
+ return NULL;
+ if (! valid_thread_id (id))
+ return PyErr_Format (PyExc_RuntimeError, "invalid thread id");
+ switch_to_thread (thread_id_to_pid (id));
+ Py_RETURN_NONE;
+}
+
+
+
void
_initialize_python (void)
{
Index: python-tromey.git/gdb/thread.c
===================================================================
--- python-tromey.git.orig/gdb/thread.c 2008-04-29 11:47:48.000000000 -0300
+++ python-tromey.git/gdb/thread.c 2008-04-29 11:54:06.000000000 -0300
@@ -60,7 +60,6 @@ static int thread_alive (struct thread_i
static void info_threads_command (char *, int);
static void thread_apply_command (char *, int);
static void restore_current_thread (ptid_t);
-static void prune_threads (void);
void
delete_step_resume_breakpoint (void *arg)
@@ -400,16 +399,23 @@ thread_alive (struct thread_info *tp)
return 1;
}
-static void
+void
prune_threads (void)
{
- struct thread_info *tp, *next;
+ struct thread_info *tp;
+ struct thread_info **prevp = &thread_list;
- for (tp = thread_list; tp; tp = next)
+ for (tp = *prevp; tp; tp = *prevp)
{
- next = tp->next;
+ /* If the thread has died, free it and unlink it from the list.
+ Otherwise, advance to the next thread. */
if (!thread_alive (tp))
- delete_thread (tp->ptid);
+ {
+ (*prevp)->next = tp->next;
+ free_thread (tp);
+ }
+ else
+ prevp = &tp->next;
}
}
--
--
[]'s
Thiago Jung Bauermann
Software Engineer
IBM Linux Technology Center