System notice: In light of the Debian OpenSSL security issue we've regenerated the server keys. See this thread for instructions and the new key fingerprints.

Commit 4d32dceb2e5e8094fe46c0a046c16071d56c14a4

Expose threads to Python.

Commit diff

gdb/Makefile.in

 
34253425
34263426python.o: $(srcdir)/python/python.c $(defs_h) $(python_h) \
34273427 $(command_h) $(libiberty_h) $(cli_decode_h) $(charset_h) $(top_h) \
3428 $(exceptions_h) $(python_internal_h) $(version_h) $(solib_h)
3428 $(exceptions_h) $(python_internal_h) $(version_h) $(solib_h) \
3429 $(inferior_h) $(gdbthread_h)
34293430 $(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
34303431python-block.o: $(srcdir)/python/block.c $(defs_h) $(block_h) $(dictionary_h) \
34313432 $(symtab_h) $(python_h) $(python_internal_h)
toggle raw diff

gdb/gdbthread.h

 
110110/* Search function to lookup a thread by 'pid'. */
111111extern struct thread_info *find_thread_pid (ptid_t ptid);
112112
113/* Prune dead threads from the list of threads. */
114extern void prune_threads (void);
115
113116/* Iterator function to call a user-provided callback function
114117 once for each known thread. */
115118typedef int (*thread_callback_func) (struct thread_info *, void *);
toggle raw diff

gdb/python/python.c

 
3131#include "symtab.h"
3232#include "source.h"
3333#include "version.h"
34#include "inferior.h"
35#include "gdbthread.h"
3436
3537#include <ctype.h>
3638
4343static PyObject *gdbpy_solib_address (PyObject *, PyObject *);
4444static PyObject *gdbpy_decode_line (PyObject *, PyObject *);
4545static PyObject *gdbpy_find_pc_function (PyObject *, PyObject *);
46static PyObject *gdbpy_get_threads (PyObject *, PyObject *);
47static PyObject *gdbpy_get_current_thread (PyObject *, PyObject *);
48static PyObject *gdbpy_switch_to_thread (PyObject *, PyObject *);
4649
4750
4851void
9090Return a tuple holding the file name (or None) and line number (or None).\n\
9191Note: may later change to return an object." },
9292
93 { "get_threads", gdbpy_get_threads, METH_NOARGS,
94 "Return a tuple holding all the valid thread IDs." },
95 { "get_current_thread", gdbpy_get_current_thread, METH_NOARGS,
96 "Return the thread ID of the current thread." },
97 { "switch_to_thread", gdbpy_switch_to_thread, METH_VARARGS,
98 "Switch to a thread, given the thread ID." },
99
93100 {NULL, NULL, 0, NULL}
94101 };
95102
486486
487487
488488
489/* Threads. */
490
491static int
492count_callback (struct thread_info *info, void *user_data)
493{
494 int *count = (int *) user_data;
495 ++*count;
496 return 0;
497}
498
499struct set_thread_info
500{
501 PyObject *tuple;
502 int index;
503};
504
505static int
506update_tuple_callback (struct thread_info *info, void *user_data)
507{
508 struct set_thread_info *tinfo = (struct set_thread_info *) user_data;
509 PyTuple_SetItem (tinfo->tuple, tinfo->index, PyInt_FromLong (info->num));
510 ++tinfo->index;
511 return 0;
512}
513
514static PyObject *
515gdbpy_get_threads (PyObject *unused1, PyObject *unused2)
516{
517 int thread_count = 0;
518 struct set_thread_info info;
519 PyObject *result;
520
521 prune_threads ();
522 target_find_new_threads ();
523
524 iterate_over_threads (count_callback, &thread_count);
525
526 if (!thread_count)
527 Py_RETURN_NONE;
528
529 result = PyTuple_New (thread_count);
530 info.tuple = result;
531 info.index = 0;
532 iterate_over_threads (update_tuple_callback, &info);
533 return result;
534}
535
536static PyObject *
537gdbpy_get_current_thread (PyObject *unused1, PyObject *unused2)
538{
539 if (PIDGET (inferior_ptid) == 0)
540 Py_RETURN_NONE;
541 return PyInt_FromLong (pid_to_thread_id (inferior_ptid));
542}
543
544static PyObject *
545gdbpy_switch_to_thread (PyObject *self, PyObject *args)
546{
547 int id;
548 if (! PyArg_ParseTuple (args, "i", &id))
549 return NULL;
550 if (! valid_thread_id (id))
551 return PyErr_Format (PyExc_RuntimeError, "invalid thread id");
552 switch_to_thread (thread_id_to_pid (id));
553 Py_RETURN_NONE;
554}
555
556
557
489558void
490559_initialize_python (void)
491560{
toggle raw diff

gdb/thread.c

 
6060static void info_threads_command (char *, int);
6161static void thread_apply_command (char *, int);
6262static void restore_current_thread (ptid_t);
63static void prune_threads (void);
6463
6564void
6665delete_step_resume_breakpoint (void *arg)
399399 return 1;
400400}
401401
402static void
402void
403403prune_threads (void)
404404{
405 struct thread_info *tp, *next;
405 struct thread_info *tp;
406 struct thread_info **prevp = &thread_list;
406407
407 for (tp = thread_list; tp; tp = next)
408 for (tp = *prevp; tp; tp = *prevp)
408409 {
409 next = tp->next;
410 /* If the thread has died, free it and unlink it from the list.
411 Otherwise, advance to the next thread. */
410412 if (!thread_alive (tp))
411 delete_thread (tp->ptid);
413 {
414 (*prevp)->next = tp->next;
415 free_thread (tp);
416 }
417 else
418 prevp = &tp->next;
412419 }
413420}
414421
toggle raw diff