2008-04-29 Tom Tromey * 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 @@ -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