binutils-gdb/gdb/python/py-infthread.c
Phil Muldoon 595939dea1 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.
2010-06-28 21:16:04 +00:00

270 lines
6.5 KiB
C

/* 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 */
};