diff options
author | Phil Muldoon <pmuldoon@redhat.com> | 2010-06-28 21:16:04 +0000 |
---|---|---|
committer | Phil Muldoon <pmuldoon@redhat.com> | 2010-06-28 21:16:04 +0000 |
commit | 595939dea136aa2721a24e6a71edba78e80fb3f5 (patch) | |
tree | 2a3c77226eb99b4b603ecb343fb060aff873e84b /gdb/python/py-infthread.c | |
parent | 4802450ac95e6cb976fa8b35f194f91a8a4fd4ea (diff) | |
download | gdb-595939dea136aa2721a24e6a71edba78e80fb3f5.zip gdb-595939dea136aa2721a24e6a71edba78e80fb3f5.tar.gz gdb-595939dea136aa2721a24e6a71edba78e80fb3f5.tar.bz2 |
2010-06-28 Phil Muldoon <pmuldoon@redhat.com>
Tom Tromey <tromey@redhat.com>
Thiago Jung Bauermann <bauerman@br.ibm.com>
* value.c (pack_unsigned_long): New function.
(value_from_ulongest): New function.
* value.h (value_from_ulongest): Declare.
* python/python.c (_initialize_python): Call
gdbpy_initialize_thread and gdbpy_initialize_inferior.
* python/python-internal.h: Define thread_object.
(gdbpy_inferiors, gdbpy_selected_thread)
(frame_info_to_frame_object, create_thread_object)
(find_thread_object, find_inferior_object)
(gdbpy_initialize_thread, gdbpy_initialize_inferiors)
(gdbpy_is_value_object, get_addr_from_python): Declare.
* python/py-value.c (builtin_type_upylong): Define.
(convert_value_from_python): Add logic for ulongest.
(gdbpy_is_value_object): New function.
* python/py-utils.c (get_addr_from_python): New function.
* python/py-frame.c (frame_info_to_frame_object): Return a PyObject.
(gdbpy_selected_frame): Use PyObject over frame_info.
* Makefile.in (SUBDIR_PYTHON_OBS): Add py-inferior and
py-infthread.
(SUBDIR_PYTHON_SRCS): Likewise.
(py-inferior.o): New Rule.
(py-infthread.o): New Rule.
* python/py-inferior.c: New File.
* python/py-infthread.c: New File.
2010-06-28 Phil Muldoon <pmuldoon@redhat.com>
Tom Tromey <tromey@redhat.com>
Thiago Jung Bauermann <bauerman@br.ibm.com>
* gdb.texinfo (Inferiors In Python): New node.
* gdb.texinfo (Threads In Python): New node.
2010-06-28 Phil Muldoon <pmuldoon@redhat.com>
Tom Tromey <tromey@redhat.com>
Thiago Jung Bauermann <bauerman@br.ibm.com>
* gdb.python/py-inferior.c: New File.
* gdb.python/py-infthread.c: New File.
* gdb.python/py-inferior.exp: New File.
* gdb.python/py-infthread.exp: New File.
Diffstat (limited to 'gdb/python/py-infthread.c')
-rw-r--r-- | gdb/python/py-infthread.c | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c new file mode 100644 index 0000000..86aba50 --- /dev/null +++ b/gdb/python/py-infthread.c @@ -0,0 +1,269 @@ +/* Python interface to inferior threads. + + Copyright (C) 2009, 2010 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "defs.h" +#include "exceptions.h" +#include "gdbthread.h" +#include "inferior.h" +#include "python-internal.h" + +static PyTypeObject thread_object_type; + +/* Require that INFERIOR be a valid inferior ID. */ +#define THPY_REQUIRE_VALID(Thread) \ + do { \ + if (!Thread->thread) \ + { \ + PyErr_SetString (PyExc_RuntimeError, \ + _("Thread no longer exists.")); \ + return NULL; \ + } \ + } while (0) + + + +thread_object * +create_thread_object (struct thread_info *tp) +{ + thread_object *thread_obj; + + thread_obj = PyObject_New (thread_object, &thread_object_type); + if (!thread_obj) + return NULL; + + thread_obj->thread = tp; + thread_obj->inf_obj = find_inferior_object (PIDGET (tp->ptid)); + Py_INCREF (thread_obj->inf_obj); + + return thread_obj; +} + + + +static void +thpy_dealloc (PyObject *self) +{ + Py_DECREF (((thread_object *) self)->inf_obj); + self->ob_type->tp_free (self); +} + +static PyObject * +thpy_get_num (PyObject *self, void *closure) +{ + thread_object *thread_obj = (thread_object *) self; + + THPY_REQUIRE_VALID (thread_obj); + + return PyLong_FromLong (thread_obj->thread->num); +} + +/* Getter for InferiorThread.ptid -> (pid, lwp, tid). + Returns a tuple with the thread's ptid components. */ +static PyObject * +thpy_get_ptid (PyObject *self, void *closure) +{ + int pid; + long tid, lwp; + thread_object *thread_obj = (thread_object *) self; + PyObject *ret; + + THPY_REQUIRE_VALID (thread_obj); + + ret = PyTuple_New (3); + if (!ret) + return NULL; + + pid = ptid_get_pid (thread_obj->thread->ptid); + lwp = ptid_get_lwp (thread_obj->thread->ptid); + tid = ptid_get_tid (thread_obj->thread->ptid); + + PyTuple_SET_ITEM (ret, 0, PyInt_FromLong (pid)); + PyTuple_SET_ITEM (ret, 1, PyInt_FromLong (lwp)); + PyTuple_SET_ITEM (ret, 2, PyInt_FromLong (tid)); + + return ret; +} + +/* Implementation of InferiorThread.switch (). + Makes this the GDB selected thread. */ +static PyObject * +thpy_switch (PyObject *self, PyObject *args) +{ + thread_object *thread_obj = (thread_object *) self; + struct cleanup *cleanup; + volatile struct gdb_exception except; + + THPY_REQUIRE_VALID (thread_obj); + + TRY_CATCH (except, RETURN_MASK_ALL) + { + switch_to_thread (thread_obj->thread->ptid); + } + GDB_PY_HANDLE_EXCEPTION (except); + + Py_RETURN_NONE; +} + +/* Implementation of InferiorThread.is_stopped () -> Boolean. + Return whether the thread is stopped. */ +static PyObject * +thpy_is_stopped (PyObject *self, PyObject *args) +{ + thread_object *thread_obj = (thread_object *) self; + + THPY_REQUIRE_VALID (thread_obj); + + if (is_stopped (thread_obj->thread->ptid)) + Py_RETURN_TRUE; + + Py_RETURN_FALSE; +} + +/* Implementation of InferiorThread.is_running () -> Boolean. + Return whether the thread is running. */ +static PyObject * +thpy_is_running (PyObject *self, PyObject *args) +{ + thread_object *thread_obj = (thread_object *) self; + + THPY_REQUIRE_VALID (thread_obj); + + if (is_running (thread_obj->thread->ptid)) + Py_RETURN_TRUE; + + Py_RETURN_FALSE; +} + +/* Implementation of InferiorThread.is_exited () -> Boolean. + Return whether the thread is exited. */ +static PyObject * +thpy_is_exited (PyObject *self, PyObject *args) +{ + thread_object *thread_obj = (thread_object *) self; + + THPY_REQUIRE_VALID (thread_obj); + + if (is_exited (thread_obj->thread->ptid)) + Py_RETURN_TRUE; + + Py_RETURN_FALSE; +} + + + +/* Implementation of gdb.selected_thread () -> gdb.InferiorThread. + Returns the selected thread object. */ +PyObject * +gdbpy_selected_thread (PyObject *self, PyObject *args) +{ + PyObject *thread_obj; + + thread_obj = (PyObject *) find_thread_object (inferior_ptid); + if (thread_obj) + { + Py_INCREF (thread_obj); + return thread_obj; + } + + Py_RETURN_NONE; +} + + + +void +gdbpy_initialize_thread (void) +{ + if (PyType_Ready (&thread_object_type) < 0) + return; + + Py_INCREF (&thread_object_type); + PyModule_AddObject (gdb_module, "InferiorThread", + (PyObject *) &thread_object_type); +} + + + +static PyGetSetDef thread_object_getset[] = +{ + { "num", thpy_get_num, NULL, "ID of the thread, as assigned by GDB.", NULL }, + { "ptid", thpy_get_ptid, NULL, "ID of the thread, as assigned by the OS.", + NULL }, + + { NULL } +}; + +static PyMethodDef thread_object_methods[] = +{ + { "switch", thpy_switch, METH_NOARGS, + "switch ()\n\ +Makes this the GDB selected thread." }, + { "is_stopped", thpy_is_stopped, METH_NOARGS, + "is_stopped () -> Boolean\n\ +Return whether the thread is stopped." }, + { "is_running", thpy_is_running, METH_NOARGS, + "is_running () -> Boolean\n\ +Return whether the thread is running." }, + { "is_exited", thpy_is_exited, METH_NOARGS, + "is_exited () -> Boolean\n\ +Return whether the thread is exited." }, + + { NULL } +}; + +static PyTypeObject thread_object_type = +{ + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ + "gdb.InferiorThread", /*tp_name*/ + sizeof (thread_object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + thpy_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ + "GDB thread object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + thread_object_methods, /* tp_methods */ + 0, /* tp_members */ + thread_object_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0 /* tp_alloc */ +}; |