This commit does three slightly different things:
1. It replaces most of the explicit get_ and set_ methods in the Python
API with (computed) attribute access [1], making it slightly less
cumbersome to use.
2. In the python bindings, the getters and setters that had to be
defined for each attribute as two functions have been replaced with
generic versions that need to be written only once for each member
type.
The generic [gs]etters access the members using their structure
offsets. Preprocessor macros are provided to compute the offsets.
Such approach is generally somewhat unsafe as it bypasses the type
system - as a compensation, test cases are present which check that
access to all the attributes works correctly.
3. The SYMS_{OK,WRONG,NOT_FOUND} constants were moved from the
GdbSharedlib class to the module level.
Related to #59 and #69.
[1]
http://docs.python.org/2.7/c-api/typeobj.html#PyTypeObject.tp_getset
Signed-off-by: Martin Milata <mmilata(a)redhat.com>
---
python/Makefile.am | 2 +
python/py_common.c | 133 +++++++++++++++
python/py_common.h | 101 ++++++++++++
python/py_gdb_frame.c | 312 ++++++++---------------------------
python/py_gdb_frame.h | 18 ---
python/py_gdb_sharedlib.c | 155 +++++-------------
python/py_gdb_sharedlib.h | 13 +-
python/py_gdb_thread.c | 57 +++----
python/py_gdb_thread.h | 4 -
python/py_java_frame.c | 248 +++++-----------------------
python/py_java_frame.h | 16 --
python/py_java_thread.c | 50 +++---
python/py_java_thread.h | 4 -
python/py_koops_frame.c | 366 ++++++------------------------------------
python/py_koops_frame.h | 25 ---
python/py_koops_stacktrace.c | 23 ++-
python/py_koops_stacktrace.h | 3 +-
python/py_module.c | 6 +
python/py_python_frame.c | 184 ++++-----------------
python/py_python_frame.h | 12 --
python/py_python_stacktrace.c | 120 +++-----------
python/py_python_stacktrace.h | 9 --
tests/python/gdb.py | 43 +++--
tests/python/java.py | 36 +++--
tests/python/koops.py | 35 ++--
tests/python/python.py | 30 +++-
tests/python/test_helpers.py | 14 ++
27 files changed, 672 insertions(+), 1347 deletions(-)
create mode 100644 python/py_common.c
create mode 100644 python/py_common.h
create mode 100644 tests/python/test_helpers.py
diff --git a/python/Makefile.am b/python/Makefile.am
index d72012a..a710e18 100644
--- a/python/Makefile.am
+++ b/python/Makefile.am
@@ -32,6 +32,8 @@ _satyr_la_SOURCES = \
py_java_stacktrace.c \
py_metrics.h \
py_metrics.c \
+ py_common.h \
+ py_common.c \
py_module.c
_satyr_la_CPPFLAGS = \
diff --git a/python/py_common.c b/python/py_common.c
new file mode 100644
index 0000000..245b58b
--- /dev/null
+++ b/python/py_common.c
@@ -0,0 +1,133 @@
+/*
+ py_common.c
+
+ Copyright (C) 2013 Red Hat, Inc.
+
+ 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 2 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "py_common.h"
+
+#include "lib/utils.h"
+
+/*
+ * Generic getters/setters that accept a struct getset_offsets as the data
+ * argument.
+ */
+
+PyObject *
+sr_py_getter_string(PyObject *self, void *data)
+{
+ struct getset_offsets *gsoff = data;
+ char *str = MEMB_T(char*, MEMB(self, gsoff->c_struct_offset),
gsoff->member_offset);
+
+ if (str == NULL)
+ Py_RETURN_NONE;
+
+ return PyString_FromString(str);
+}
+
+int
+sr_py_setter_string(PyObject *self, PyObject *rhs, void *data)
+{
+ struct getset_offsets *gsoff = data;
+
+ char *newvalue = PyString_AsString(rhs);
+ if (!newvalue)
+ return -1;
+
+ char *str = MEMB_T(char*, MEMB(self, gsoff->c_struct_offset),
gsoff->member_offset);
+ free(str);
+ MEMB_T(char*, MEMB(self, gsoff->c_struct_offset), gsoff->member_offset) =
sr_strdup(newvalue);
+
+ return 0;
+}
+
+PyObject *
+sr_py_getter_uint32(PyObject *self, void *data)
+{
+ struct getset_offsets *gsoff = data;
+ uint32_t num = MEMB_T(uint32_t, MEMB(self, gsoff->c_struct_offset),
gsoff->member_offset);
+ return PyInt_FromLong(num);
+}
+
+int
+sr_py_setter_uint32(PyObject *self, PyObject *rhs, void *data)
+{
+ struct getset_offsets *gsoff = data;
+
+ long newvalue = PyInt_AsLong(rhs);
+ if (PyErr_Occurred())
+ return -1;
+
+ if (newvalue < 0)
+ {
+ PyErr_SetString(PyExc_ValueError, "Value must not be negative.");
+ return -1;
+ }
+
+ MEMB_T(uint32_t, MEMB(self, gsoff->c_struct_offset), gsoff->member_offset)
+ = (uint32_t)newvalue;
+ return 0;
+}
+
+PyObject *
+sr_py_getter_bool(PyObject *self, void *data)
+{
+ struct getset_offsets *gsoff = data;
+
+ bool b = MEMB_T(bool, MEMB(self, gsoff->c_struct_offset),
gsoff->member_offset);
+ return PyBool_FromLong(b);
+}
+
+int
+sr_py_setter_bool(PyObject *self, PyObject *rhs, void *data)
+{
+ struct getset_offsets *gsoff = data;
+
+ if (!PyBool_Check(rhs))
+ {
+ PyErr_SetString(PyExc_TypeError, "Boolean required.");
+ return -1;
+ }
+
+ bool newvalue = (rhs == Py_True);
+ MEMB_T(bool, MEMB(self, gsoff->c_struct_offset), gsoff->member_offset) =
newvalue;
+
+ return 0;
+}
+
+PyObject *
+sr_py_getter_uint64(PyObject *self, void *data)
+{
+ struct getset_offsets *gsoff = data;
+
+ uint64_t num
+ = MEMB_T(uint64_t, MEMB(self, gsoff->c_struct_offset),
gsoff->member_offset);
+ return PyLong_FromUnsignedLongLong(num);
+}
+
+int
+sr_py_setter_uint64(PyObject *self, PyObject *rhs, void *data)
+{
+ struct getset_offsets *gsoff = data;
+
+ unsigned long long newvalue = PyInt_AsUnsignedLongLongMask(rhs);
+ if (PyErr_Occurred())
+ return -1;
+
+ MEMB_T(uint64_t, MEMB(self, gsoff->c_struct_offset), gsoff->member_offset) =
newvalue;
+ return 0;
+}
diff --git a/python/py_common.h b/python/py_common.h
new file mode 100644
index 0000000..c778cee
--- /dev/null
+++ b/python/py_common.h
@@ -0,0 +1,101 @@
+/*
+ py_common.h
+
+ Copyright (C) 2013 Red Hat, Inc.
+
+ 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 2 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#ifndef SATYR_PY_COMMON_H
+#define SATYR_PY_COMMON_H
+
+/**
+ * @file
+ * @brief Common routines for python bindings.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Python.h>
+#include <structmember.h>
+
+/*
+ * Struct member access using offsets. The second variant is useful for nested
+ * structures.
+ *
+ * MEMB_T(type, offsetof(typeof(st), member)) == (type)(st->member)
+ * MEMB(st, offsetof(typeof(st), member)) == (void*)(st->member)
+ */
+#define MEMB_T(type, st, off) *(type *)((char*)st + off)
+#define MEMB(st, off) MEMB_T(void*, st, off)
+
+/*
+ * This struct is used for generic getters and setters. Most of satyr's python
+ * object structures contain pointer to a corresponding C structure, which in
+ * turn contains the members that are exposed in the python API.
+ *
+ * If we know the offset of the pointer to the C structure in the python object
+ * and the offset of the member in the C structure, we can access the member
+ * using generic (per-type) functions, declared further below.
+ */
+struct getset_offsets
+{
+ size_t c_struct_offset;
+ size_t member_offset;
+};
+
+/*
+ * These macros make it possible to initialize several struct getset_offsets
+ * without typing too much and entering the offsets by hand.
+ *
+ * You need to define GSOFF_PY_STRUCT to be the type of the structure defining
+ * the python object, GSOFF_PY_MEMBER to be the name of its member pointing to
+ * the C structure, and GSOFF_C_STRUCT to be the type of the C structure. Use
+ * GSOFF_MEMBER for each member you want to access, GSOFF_MEMBER(m) defines the
+ * variable gsoff_m which can be used in the declaration of getters and
+ * setters.
+ *
+ * See python/py_gdb_frame.c for example usage.
+ */
+#define GSOFF_START static struct getset_offsets
+#define GSOFF_MEMBER(c_member) \
+ gsoff_ ## c_member = { \
+ .c_struct_offset = offsetof(struct GSOFF_PY_STRUCT, GSOFF_PY_MEMBER), \
+ .member_offset = offsetof(struct GSOFF_C_STRUCT, c_member) \
+ }
+#define GSOFF_END ;
+
+/*
+ * Generic getters/setters that accept a struct getset_offsets as the data
+ * argument.
+ */
+PyObject *sr_py_getter_string(PyObject *self, void *data);
+int sr_py_setter_string(PyObject *self, PyObject *rhs, void *data);
+
+PyObject *sr_py_getter_uint32(PyObject *self, void *data);
+int sr_py_setter_uint32(PyObject *self, PyObject *rhs, void *data);
+
+PyObject *sr_py_getter_bool(PyObject *self, void *data);
+int sr_py_setter_bool(PyObject *self, PyObject *rhs, void *data);
+
+PyObject *sr_py_getter_uint64(PyObject *self, void *data);
+int sr_py_setter_uint64(PyObject *self, PyObject *rhs, void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SATYR_PY_COMMON_H */
diff --git a/python/py_gdb_frame.c b/python/py_gdb_frame.c
index b69b1f6..36b7170 100644
--- a/python/py_gdb_frame.c
+++ b/python/py_gdb_frame.c
@@ -17,6 +17,7 @@
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "py_common.h"
#include "py_gdb_frame.h"
#include <inttypes.h>
@@ -31,53 +32,14 @@
"satyr.GdbFrame() - creates an empty frame\n" \
"satyr.GdbFrame(str) - parses str and fills the frame
object"
-#define f_get_function_name_doc "Usage: frame.get_function_name()\n" \
- "Returns: string - function name"
-
-#define f_set_function_name_doc "Usage: frame.set_function_name(newname)\n" \
- "newname: string - new function name"
-
-#define f_get_function_type_doc "Usage: frame.get_function_type()\n" \
- "Returns: string - function type"
-
-#define f_set_function_type_doc "Usage: frame.set_function_type(newtype)\n" \
- "newtype: string - new function type"
-
-#define f_get_number_doc "Usage: frame.get_number()\n" \
- "Returns: positive integer - frame number"
-
-#define f_set_number_doc "Usage: frame.set_number(N)\n" \
- "N: positive integer - new frame number"
-
-#define f_get_source_line_doc "Usage: frame.get_source_line()\n" \
- "Returns: positive integer - source line number"
-
-#define f_set_source_line_doc "Usage: frame.set_source_line(N)\n" \
- "N: positive integer - new source line number"
-
-#define f_get_source_file_doc "Usage: frame.get_source_file()\n" \
- "Returns: string - source file name"
-
-#define f_set_source_file_doc "Usage: frame.set_source_file(newname)\n" \
- "newname: string - new source file name"
-
-#define f_get_signal_handler_called_doc "Usage:
frame.get_signal_handler_called()\n" \
- "Returns: integer - 0 = False, 1 =
True"
-
-#define f_set_signal_handler_called_doc "Usage:
frame.set_signal_handler_called(N)\n" \
- "N: integer - 0 = False, anything else =
True"
-
-#define f_get_address_doc "Usage: frame.get_address()\n" \
- "Returns: positive long integer - address"
-
-#define f_set_address_doc "Usage: frame.set_address(N)\n" \
- "N: positive long integer - new address"
-
-#define f_get_library_name_doc "Usage: frame.get_library_name()\n" \
- "Returns: string - library name"
-
-#define f_set_library_name_doc "Usage: frame.set_library_name(newname)\n" \
- "newname: string - new library name"
+#define f_function_name_doc "Function name (string)"
+#define f_function_type_doc "Function type (string)"
+#define f_number_doc "Frame number (positive integer)"
+#define f_source_file_doc "Source file name (string)"
+#define f_source_line_doc "Source line number (positive integer)"
+#define f_signal_handler_called_doc "True if the frame is signal handler
(bool)"
+#define f_address_doc "Address of the current instruction
(long)"
+#define f_library_name_doc "Executable file name (string)"
#define f_dup_doc "Usage: frame.dup()\n" \
"Returns: satyr.GdbFrame - a new clone of frame\n" \
@@ -109,28 +71,66 @@
static PyMethodDef
frame_methods[] =
{
- /* getters & setters */
- { "get_function_name", sr_py_gdb_frame_get_function_name,
METH_NOARGS, f_get_function_name_doc },
- { "set_function_name", sr_py_gdb_frame_set_function_name,
METH_VARARGS, f_set_function_name_doc },
- { "get_function_type", sr_py_gdb_frame_get_function_type,
METH_NOARGS, f_get_function_type_doc },
- { "set_function_type", sr_py_gdb_frame_set_function_type,
METH_VARARGS, f_set_function_type_doc },
- { "get_number", sr_py_gdb_frame_get_number,
METH_NOARGS, f_get_number_doc },
- { "set_number", sr_py_gdb_frame_set_number,
METH_VARARGS, f_set_number_doc },
- { "get_source_file", sr_py_gdb_frame_get_source_file,
METH_NOARGS, f_get_source_file_doc },
- { "set_source_file", sr_py_gdb_frame_set_source_file,
METH_VARARGS, f_set_source_file_doc },
- { "get_source_line", sr_py_gdb_frame_get_source_line,
METH_NOARGS, f_get_source_line_doc },
- { "set_source_line", sr_py_gdb_frame_set_source_line,
METH_VARARGS, f_set_source_line_doc },
- { "get_signal_handler_called", sr_py_gdb_frame_get_signal_handler_called,
METH_NOARGS, f_get_signal_handler_called_doc },
- { "set_signal_handler_called", sr_py_gdb_frame_set_signal_handler_called,
METH_VARARGS, f_set_signal_handler_called_doc },
- { "get_address", sr_py_gdb_frame_get_address,
METH_NOARGS, f_get_address_doc },
- { "set_address", sr_py_gdb_frame_set_address,
METH_VARARGS, f_set_address_doc },
- { "get_library_name", sr_py_gdb_frame_get_library_name,
METH_NOARGS, f_get_library_name_doc },
- { "set_library_name", sr_py_gdb_frame_set_library_name,
METH_VARARGS, f_set_library_name_doc },
/* methods */
- { "dup", sr_py_gdb_frame_dup,
METH_NOARGS, f_dup_doc },
- { "cmp", sr_py_gdb_frame_cmp,
METH_VARARGS, f_cmp_doc },
- { "calls_func", sr_py_gdb_frame_calls_func,
METH_VARARGS, f_calls_func_doc },
- { "calls_func_in_file", sr_py_gdb_frame_calls_func_in_file,
METH_VARARGS, f_calls_func_in_file_doc },
+ { "dup", sr_py_gdb_frame_dup, METH_NOARGS,
f_dup_doc },
+ { "cmp", sr_py_gdb_frame_cmp, METH_VARARGS,
f_cmp_doc },
+ { "calls_func", sr_py_gdb_frame_calls_func, METH_VARARGS,
f_calls_func_doc },
+ { "calls_func_in_file", sr_py_gdb_frame_calls_func_in_file, METH_VARARGS,
f_calls_func_in_file_doc },
+ { NULL },
+};
+
+/*
+ * This sequence of #defines and macros expands to definition of struct
+ * getset_offsets, one for each member to be accessed with the generic
+ * getters/setters.
+ *
+ * Python objects for GDB frames store data in struct sr_py_gdb_frame, which
+ * contains pointer named frame that points to the GDB frame C structure named
+ * struct sr_gdb_frame. Most of the satyr python object follow similar scheme,
+ * which allows us to use generic getters/setters that only need to know two
+ * offsets.
+ */
+
+/* GSOFF_PY_STRUCT must be defined to the type of the python object structure (without
struct keyword). */
+#define GSOFF_PY_STRUCT sr_py_gdb_frame
+
+/* GSOFF_PY_MEMBER must be defined to name of GSOFF_PY_STRUCT's member that points to
the satyr C structure. */
+#define GSOFF_PY_MEMBER frame
+
+/* GSOFF_C_STRUCT must be defined to the type of the C structure (without struct keyword)
*/
+#define GSOFF_C_STRUCT sr_gdb_frame
+
+/*
+ * Individual GSOFF_MEMBER invocations need to be surrounded by GSOFF_START and
+ * GSOFF_END and need to be separated by commas (which must not be after the
+ * last invocation). The order does not matter.
+ *
+ * E.g. the GSOFF_MEMBER(function_name) expands to definition of global
+ * variable gsoff_function_name containing the right offsets, which is then
+ * used int the frame_getset[] definition below.
+ */
+GSOFF_START
+GSOFF_MEMBER(function_name),
+GSOFF_MEMBER(function_type),
+GSOFF_MEMBER(source_file),
+GSOFF_MEMBER(number),
+GSOFF_MEMBER(source_line),
+GSOFF_MEMBER(signal_handler_called),
+GSOFF_MEMBER(address),
+GSOFF_MEMBER(library_name)
+GSOFF_END
+
+static PyGetSetDef
+frame_getset[] =
+{
+ { (char*)"function_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_function_name_doc, &gsoff_function_name },
+ { (char*)"function_type", sr_py_getter_string, sr_py_setter_string,
(char*)f_function_type_doc, &gsoff_function_type },
+ { (char*)"number", sr_py_getter_uint32, sr_py_setter_uint32,
(char*)f_number_doc, &gsoff_number },
+ { (char*)"source_file", sr_py_getter_string, sr_py_setter_string,
(char*)f_source_file_doc, &gsoff_source_file },
+ { (char*)"source_line", sr_py_getter_uint32, sr_py_setter_uint32,
(char*)f_source_line_doc, &gsoff_source_line },
+ { (char*)"signal_handler_called", sr_py_getter_bool, sr_py_setter_bool,
(char*)f_signal_handler_called_doc, &gsoff_signal_handler_called },
+ { (char*)"address", sr_py_getter_uint64, sr_py_setter_uint64,
(char*)f_address_doc, &gsoff_address },
+ { (char*)"library_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_library_name_doc, &gsoff_library_name },
{ NULL },
};
@@ -165,9 +165,9 @@ sr_py_gdb_frame_type =
0, /* tp_weaklistoffset */
NULL, /* tp_iter */
NULL, /* tp_iternext */
- frame_methods, /* tp_methods */
+ frame_methods, /* tp_methods */
NULL, /* tp_members */
- NULL, /* tp_getset */
+ frame_getset, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
@@ -249,178 +249,6 @@ sr_py_gdb_frame_str(PyObject *self)
return result;
}
-/* getters & setters */
-
-/* function_name */
-PyObject *
-sr_py_gdb_frame_get_function_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_gdb_frame*)self)->frame->function_name);
-}
-
-PyObject *
-sr_py_gdb_frame_set_function_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_gdb_frame *frame = ((struct sr_py_gdb_frame*)self)->frame;
- free(frame->function_name);
- frame->function_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* function_type */
-PyObject *
-sr_py_gdb_frame_get_function_type(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_gdb_frame*)self)->frame->function_type);
-}
-
-PyObject *
-sr_py_gdb_frame_set_function_type(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_gdb_frame *frame = ((struct sr_py_gdb_frame*)self)->frame;
- free(frame->function_type);
- frame->function_type = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* number */
-PyObject *
-sr_py_gdb_frame_get_number(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("i", ((struct
sr_py_gdb_frame*)self)->frame->number);
-}
-
-PyObject *
-sr_py_gdb_frame_set_number(PyObject *self, PyObject *args)
-{
- int newvalue;
- if (!PyArg_ParseTuple(args, "i", &newvalue))
- return NULL;
-
- if (newvalue < 0)
- {
- PyErr_SetString(PyExc_ValueError, "Frame number must not be
negative.");
- return NULL;
- }
-
- struct sr_gdb_frame *frame = ((struct sr_py_gdb_frame*)self)->frame;
- frame->number = newvalue;
- Py_RETURN_NONE;
-}
-
-/* source_file */
-PyObject *
-sr_py_gdb_frame_get_source_file(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_gdb_frame*)self)->frame->source_file);
-}
-
-PyObject *
-sr_py_gdb_frame_set_source_file(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_gdb_frame *frame = ((struct sr_py_gdb_frame*)self)->frame;
- free(frame->source_file);
- frame->source_file = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* source_line */
-PyObject *
-sr_py_gdb_frame_get_source_line(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("i", ((struct
sr_py_gdb_frame*)self)->frame->source_line);
-}
-
-PyObject *
-sr_py_gdb_frame_set_source_line(PyObject *self, PyObject *args)
-{
- int newvalue;
- if (!PyArg_ParseTuple(args, "i", &newvalue))
- return NULL;
-
- if (newvalue < 0)
- {
- PyErr_SetString(PyExc_ValueError, "Source line must not be
negative.");
- return NULL;
- }
-
- struct sr_gdb_frame *frame = ((struct sr_py_gdb_frame*)self)->frame;
- frame->source_line = newvalue;
- Py_RETURN_NONE;
-}
-
-/* signal_handler_called */
-PyObject *
-sr_py_gdb_frame_get_signal_handler_called(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("i", ((struct
sr_py_gdb_frame*)self)->frame->signal_handler_called);
-}
-
-PyObject *
-sr_py_gdb_frame_set_signal_handler_called(PyObject *self, PyObject *args)
-{
- int newvalue;
- if (!PyArg_ParseTuple(args, "i", &newvalue))
- return NULL;
-
- struct sr_gdb_frame *frame = ((struct sr_py_gdb_frame*)self)->frame;
- frame->signal_handler_called = newvalue ? 1 : 0;
- Py_RETURN_NONE;
-}
-
-/* address */
-PyObject *
-sr_py_gdb_frame_get_address(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("K",
- (unsigned long long)(((struct sr_py_gdb_frame*)self)->frame->address));
-}
-
-PyObject *
-sr_py_gdb_frame_set_address(PyObject *self, PyObject *args)
-{
- unsigned long long newvalue;
- if (!PyArg_ParseTuple(args, "K", &newvalue))
- return NULL;
-
- struct sr_gdb_frame *frame = ((struct sr_py_gdb_frame*)self)->frame;
- frame->address = newvalue;
- Py_RETURN_NONE;
-}
-
-/* library_name */
-PyObject *
-sr_py_gdb_frame_get_library_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_gdb_frame*)self)->frame->library_name);
-}
-
-PyObject *
-sr_py_gdb_frame_set_library_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_gdb_frame *frame = ((struct sr_py_gdb_frame*)self)->frame;
- free(frame->library_name);
- frame->library_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-
/* methods */
PyObject *
sr_py_gdb_frame_dup(PyObject *self, PyObject *args)
diff --git a/python/py_gdb_frame.h b/python/py_gdb_frame.h
index 8cf5691..4926014 100644
--- a/python/py_gdb_frame.h
+++ b/python/py_gdb_frame.h
@@ -56,24 +56,6 @@ void sr_py_gdb_frame_free(PyObject *object);
*/
PyObject *sr_py_gdb_frame_str(PyObject *self);
-/* getters & setters */
-PyObject *sr_py_gdb_frame_get_function_name(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_set_function_name(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_get_function_type(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_set_function_type(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_get_number(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_set_number(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_get_source_file(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_set_source_file(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_get_source_line(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_set_source_line(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_get_signal_handler_called(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_set_signal_handler_called(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_get_address(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_set_address(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_get_library_name(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_frame_set_library_name(PyObject *self, PyObject *args);
-
/* methods */
PyObject *sr_py_gdb_frame_dup(PyObject *self, PyObject *args);
PyObject *sr_py_gdb_frame_cmp(PyObject *self, PyObject *args);
diff --git a/python/py_gdb_sharedlib.c b/python/py_gdb_sharedlib.c
index 4737884..ed502f5 100644
--- a/python/py_gdb_sharedlib.c
+++ b/python/py_gdb_sharedlib.c
@@ -1,61 +1,35 @@
+#include "py_common.h"
#include "py_gdb_sharedlib.h"
#include "lib/gdb_sharedlib.h"
#include "lib/utils.h"
#define sharedlib_doc "satyr.GdbSharedlib - class representing a shared library
loaded at the moment of crash"
-#define s_get_from_doc "Usage: sharedlib.get_from()\n" \
- "Returns: long - address where lib's memory begins"
-
-#define s_set_from_doc "Usage: sharedlib.set_from(newvalue)\n" \
- "Newvalue: long - address where lib's memory
begins"
-
-#define s_get_to_doc "Usage: sharedlib.get_to()\n" \
- "Returns: long - address where lib's memory ends"
-
-#define s_set_to_doc "Usage: sharedlib.set_to(newvalue)\n" \
- "Newvalue: long - address where lib's memory ends"
-
-#define s_get_symbols_doc "Usage: sharedlib.get_symbols()\n" \
- "Returns: SYMS_OK / SYMS_NOT_FOUND / SYMS_WRONG"
-
-#define s_set_symbols_doc "Usage: sharedlib.set_symbols(newvalue)\n" \
- "Newvalue: SYMS_OK / SYMS_NOT_FOUND / SYMS_WRONG"
-
-#define s_get_soname_doc "Usage: sharedlib.get_soname()\n" \
- "Returns: string - library filename"
-
-#define s_set_soname_doc "Usage: sharedlib.set_soname(newvalue)\n" \
- "Newvalue: string - library filename"
-
-#define s_syms_ok_doc (char *)"Constant. Debug symbols for the library were loaded
successfully."
-
-#define s_syms_wrong_doc (char *)"Constant. Debug symbols for the library were
present, but did not match."
-
-#define s_syms_not_found_doc (char *)"Constant. Debug symbols for the library were
not found."
-
-static PyMethodDef
-gdb_sharedlib_methods[] =
+#define s_from_doc "Address where lib's memory begins (long)"
+#define s_to_doc "Address where lib's memory ends (long)"
+#define s_symbols_doc "Symbol state (satyr.SYMS_OK / satyr.SYMS_NOT_FOUND /
satyr.SYMS_WRONG)\n" \
+ "SYMS_OK: Debug symbols for the library were loaded
successfully.\n" \
+ "SYMS_WRONG: Debug symbols for the library were present,
but did not match.\n" \
+ "SYMS_NOT_FOUND: Debug symbols for the library were not
found."
+#define s_soname_doc "Library file name (string)"
+
+/* See python/py_common.h and python/py_gdb_frame.c for generic getters/setters
documentation. */
+#define GSOFF_PY_STRUCT sr_py_gdb_sharedlib
+#define GSOFF_PY_MEMBER sharedlib
+#define GSOFF_C_STRUCT sr_gdb_sharedlib
+GSOFF_START
+GSOFF_MEMBER(from),
+GSOFF_MEMBER(to),
+GSOFF_MEMBER(soname)
+GSOFF_END
+
+static PyGetSetDef
+gdb_sharedlib_getset[] =
{
- /* getters & setters */
- { "get_from", sr_py_gdb_sharedlib_get_from, METH_NOARGS,
s_get_from_doc },
- { "set_from", sr_py_gdb_sharedlib_set_from, METH_VARARGS,
s_set_from_doc },
- { "get_to", sr_py_gdb_sharedlib_get_to, METH_NOARGS,
s_get_to_doc },
- { "set_to", sr_py_gdb_sharedlib_set_to, METH_VARARGS,
s_set_to_doc },
- { "get_symbols", sr_py_gdb_sharedlib_get_symbols, METH_NOARGS,
s_get_symbols_doc },
- { "set_symbols", sr_py_gdb_sharedlib_set_symbols, METH_VARARGS,
s_set_symbols_doc },
- { "get_soname", sr_py_gdb_sharedlib_get_soname, METH_NOARGS,
s_get_soname_doc },
- { "set_soname", sr_py_gdb_sharedlib_set_soname, METH_VARARGS,
s_set_soname_doc },
- /* methods */
- { NULL },
-};
-
-static PyMemberDef
-gdb_sharedlib_members[] =
-{
- { (char *)"SYMS_OK", T_INT, offsetof(struct sr_py_gdb_sharedlib,
syms_ok), READONLY, s_syms_ok_doc },
- { (char *)"SYMS_WRONG", T_INT, offsetof(struct sr_py_gdb_sharedlib,
syms_wrong), READONLY, s_syms_wrong_doc },
- { (char *)"SYMS_NOT_FOUND", T_INT, offsetof(struct sr_py_gdb_sharedlib,
syms_not_found), READONLY, s_syms_not_found_doc },
+ { (char*)"start_address", sr_py_getter_uint64,
sr_py_setter_uint64, (char*)s_from_doc, &gsoff_from },
+ { (char*)"end_address", sr_py_getter_uint64,
sr_py_setter_uint64, (char*)s_to_doc, &gsoff_to },
+ { (char*)"symbols", sr_py_gdb_sharedlib_get_symbols,
sr_py_gdb_sharedlib_set_symbols, (char*)s_symbols_doc, NULL },
+ { (char*)"soname", sr_py_getter_string,
sr_py_setter_string, (char*)s_soname_doc, &gsoff_soname },
{ NULL },
};
@@ -90,9 +64,9 @@ sr_py_gdb_sharedlib_type =
0, /* tp_weaklistoffset */
NULL, /* tp_iter */
NULL, /* tp_iternext */
- gdb_sharedlib_methods, /* tp_methods */
- gdb_sharedlib_members, /* tp_members */
- NULL, /* tp_getset */
+ NULL, /* tp_methods */
+ NULL, /* tp_members */
+ gdb_sharedlib_getset, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
@@ -122,9 +96,6 @@ sr_py_gdb_sharedlib_new(PyTypeObject *object, PyObject *args, PyObject
*kwds)
return PyErr_NoMemory();
so->sharedlib = sr_gdb_sharedlib_new();
- so->syms_ok = SYMS_OK;
- so->syms_wrong = SYMS_WRONG;
- so->syms_not_found = SYMS_NOT_FOUND;
return (PyObject *)so;
}
@@ -147,80 +118,26 @@ sr_py_gdb_sharedlib_str(PyObject *self)
/* getters & setters */
-/* function_name */
-PyObject *
-sr_py_gdb_sharedlib_get_from(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("l", ((struct
sr_py_gdb_sharedlib*)self)->sharedlib->from);
-}
-
-PyObject *
-sr_py_gdb_sharedlib_set_from(PyObject *self, PyObject *args)
-{
- unsigned long long newvalue;
- if (!PyArg_ParseTuple(args, "l", &newvalue))
- return NULL;
-
- ((struct sr_py_gdb_sharedlib *)self)->sharedlib->from = newvalue;
- Py_RETURN_NONE;
-}
-
PyObject *
-sr_py_gdb_sharedlib_get_to(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("l", ((struct
sr_py_gdb_sharedlib*)self)->sharedlib->to);
-}
-
-PyObject *
-sr_py_gdb_sharedlib_set_to(PyObject *self, PyObject *args)
-{
- unsigned long long newvalue;
- if (!PyArg_ParseTuple(args, "l", &newvalue))
- return NULL;
-
- ((struct sr_py_gdb_sharedlib *)self)->sharedlib->to = newvalue;
- Py_RETURN_NONE;
-}
-
-PyObject *
-sr_py_gdb_sharedlib_get_symbols(PyObject *self, PyObject *args)
+sr_py_gdb_sharedlib_get_symbols(PyObject *self, void *data)
{
return Py_BuildValue("i", ((struct
sr_py_gdb_sharedlib*)self)->sharedlib->symbols);
}
-PyObject *
-sr_py_gdb_sharedlib_set_symbols(PyObject *self, PyObject *args)
+int
+sr_py_gdb_sharedlib_set_symbols(PyObject *self, PyObject *rhs, void *data)
{
- int newvalue;
- if (!PyArg_ParseTuple(args, "i", &newvalue))
- return NULL;
+ long newvalue = PyInt_AsLong(rhs);
+ if (PyErr_Occurred())
+ return -1;
if (newvalue != SYMS_OK && newvalue != SYMS_WRONG && newvalue !=
SYMS_NOT_FOUND)
{
PyErr_SetString(PyExc_ValueError, "Symbols must be either SYMS_OK, "
"SYMS_WRONG or SYMS_NOT_FOUND.");
- return NULL;
+ return -1;
}
((struct sr_py_gdb_sharedlib *)self)->sharedlib->symbols = newvalue;
- Py_RETURN_NONE;
-}
-
-PyObject *
-sr_py_gdb_sharedlib_get_soname(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_gdb_sharedlib*)self)->sharedlib->soname);
-}
-
-PyObject *
-sr_py_gdb_sharedlib_set_soname(PyObject *self, PyObject *args)
-{
- char *soname;
- if (!PyArg_ParseTuple(args, "s", &soname))
- return NULL;
-
- struct sr_py_gdb_sharedlib *this = (struct sr_py_gdb_sharedlib*)self;
- free(this->sharedlib->soname);
- this->sharedlib->soname = sr_strdup(soname);
- Py_RETURN_NONE;
+ return 0;
}
diff --git a/python/py_gdb_sharedlib.h b/python/py_gdb_sharedlib.h
index 1a6ca92..335a2e7 100644
--- a/python/py_gdb_sharedlib.h
+++ b/python/py_gdb_sharedlib.h
@@ -38,9 +38,6 @@ struct sr_py_gdb_sharedlib
{
PyObject_HEAD
struct sr_gdb_sharedlib *sharedlib;
- int syms_ok;
- int syms_wrong;
- int syms_not_found;
};
/* constructor */
@@ -55,14 +52,8 @@ void sr_py_gdb_sharedlib_free(PyObject *object);
PyObject *sr_py_gdb_sharedlib_str(PyObject *self);
/* getters & setters */
-PyObject *sr_py_gdb_sharedlib_get_from(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_sharedlib_set_from(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_sharedlib_get_to(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_sharedlib_set_to(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_sharedlib_get_soname(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_sharedlib_set_soname(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_sharedlib_get_symbols(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_sharedlib_set_symbols(PyObject *self, PyObject *args);
+PyObject *sr_py_gdb_sharedlib_get_symbols(PyObject *self, void *data);
+int sr_py_gdb_sharedlib_set_symbols(PyObject *self, PyObject *rhs, void *data);
#ifdef __cplusplus
}
diff --git a/python/py_gdb_thread.c b/python/py_gdb_thread.c
index dd48a90..7aed856 100644
--- a/python/py_gdb_thread.c
+++ b/python/py_gdb_thread.c
@@ -1,3 +1,4 @@
+#include "py_common.h"
#include "py_gdb_thread.h"
#include "py_gdb_frame.h"
#include "lib/strbuf.h"
@@ -11,11 +12,7 @@
"satyr.GdbThread(str) - parses str and fills the thread
object\n" \
"satyr.GdbThread(str, only_funs=True) - parses list of function
names"
-#define t_get_number_doc "Usage: thread.get_number()\n" \
- "Returns: positive integer - thread number"
-
-#define t_set_number_doc "Usage: thread.set_number(N)\n" \
- "N: positive integer - new thread number"
+#define t_number_doc "Thread number (positive integer)"
#define t_dup_doc "Usage: thread.dup()\n" \
"Returns: satyr.GdbThread - a new clone of thread\n" \
@@ -48,9 +45,6 @@
static PyMethodDef
gdb_thread_methods[] =
{
- /* getters & setters */
- { "get_number", sr_py_gdb_thread_get_number, METH_NOARGS,
t_get_number_doc },
- { "set_number", sr_py_gdb_thread_set_number, METH_VARARGS,
t_set_number_doc },
/* methods */
{ "cmp", sr_py_gdb_thread_cmp, METH_VARARGS,
t_cmp_doc },
{ "dup", sr_py_gdb_thread_dup, METH_NOARGS,
t_dup_doc },
@@ -67,6 +61,21 @@ gdb_thread_members[] =
{ NULL },
};
+/* See python/py_common.h and python/py_gdb_frame.c for generic getters/setters
documentation. */
+#define GSOFF_PY_STRUCT sr_py_gdb_thread
+#define GSOFF_PY_MEMBER thread
+#define GSOFF_C_STRUCT sr_gdb_thread
+GSOFF_START
+GSOFF_MEMBER(number)
+GSOFF_END
+
+static PyGetSetDef
+gdb_thread_getset[] =
+{
+ { (char*)"number", sr_py_getter_uint32, sr_py_setter_uint32,
(char*)t_number_doc, &gsoff_number },
+ { NULL },
+};
+
PyTypeObject sr_py_gdb_thread_type =
{
PyObject_HEAD_INIT(NULL)
@@ -97,9 +106,9 @@ PyTypeObject sr_py_gdb_thread_type =
0, /* tp_weaklistoffset */
NULL, /* tp_iter */
NULL, /* tp_iternext */
- gdb_thread_methods, /* tp_methods */
- gdb_thread_members, /* tp_members */
- NULL, /* tp_getset */
+ gdb_thread_methods, /* tp_methods */
+ gdb_thread_members, /* tp_members */
+ gdb_thread_getset, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
@@ -301,32 +310,6 @@ sr_py_gdb_thread_str(PyObject *self)
return result;
}
-/* getters & setters */
-PyObject *
-sr_py_gdb_thread_get_number(PyObject *self, PyObject *args)
-{
- struct sr_py_gdb_thread *this = (struct sr_py_gdb_thread *)self;
- return Py_BuildValue("i", this->thread->number);
-}
-
-PyObject *
-sr_py_gdb_thread_set_number(PyObject *self, PyObject *args)
-{
- struct sr_py_gdb_thread *this = (struct sr_py_gdb_thread *)self;
- int newvalue;
- if (!PyArg_ParseTuple(args, "i", &newvalue))
- return NULL;
-
- if (newvalue < 0)
- {
- PyErr_SetString(PyExc_ValueError, "Thread number must not be
negative.");
- return NULL;
- }
-
- this->thread->number = newvalue;
- Py_RETURN_NONE;
-}
-
/* methods */
PyObject *
sr_py_gdb_thread_dup(PyObject *self, PyObject *args)
diff --git a/python/py_gdb_thread.h b/python/py_gdb_thread.h
index 39da841..c2c4611 100644
--- a/python/py_gdb_thread.h
+++ b/python/py_gdb_thread.h
@@ -57,10 +57,6 @@ void sr_py_gdb_thread_free(PyObject *object);
/* str */
PyObject *sr_py_gdb_thread_str(PyObject *self);
-/* getters & setters */
-PyObject *sr_py_gdb_thread_get_number(PyObject *self, PyObject *args);
-PyObject *sr_py_gdb_thread_set_number(PyObject *self, PyObject *args);
-
/* methods */
PyObject *sr_py_gdb_thread_dup(PyObject *self, PyObject *args);
PyObject *sr_py_gdb_thread_cmp(PyObject *self, PyObject *args);
diff --git a/python/py_java_frame.c b/python/py_java_frame.c
index 212e8d9..f1b0491 100644
--- a/python/py_java_frame.c
+++ b/python/py_java_frame.c
@@ -17,6 +17,7 @@
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "py_common.h"
#include "py_java_frame.h"
#include "lib/location.h"
#include "lib/strbuf.h"
@@ -28,47 +29,13 @@
"satyr.JavaFrame() - creates an empty frame\n" \
"satyr.JavaFrame(str) - parses str and fills the frame
object"
-#define f_get_name_doc "Usage: frame.get_name()\n" \
- "Returns: string - fully qualified domain
name"
-
-#define f_set_name_doc "Usage: frame.set_name(newname)\n" \
- "newname: string - new name"
-
-#define f_get_file_name_doc "Usage: frame.get_file_name()\n" \
- "Returns: string - file name"
-
-#define f_set_file_name_doc "Usage: frame.set_file_name(newname)\n" \
- "newname: string - new file name"
-
-#define f_get_file_line_doc "Usage: frame.get_file_line()\n" \
- "Returns: unsigned int - file line"
-
-#define f_set_file_line_doc "Usage: frame.set_file_line(newline)\n" \
- "newline: unsigned int - new file line"
-
-#define f_get_class_path_doc "Usage: frame.get_class_path()\n" \
- "Returns: string - class path"
-
-#define f_set_class_path_doc "Usage: frame.set_class_path(newcp)\n" \
- "newcp: string - new class path"
-
-#define f_is_native_doc "Usage: frame.is_native()\n" \
- "Returns: boolean - true if method is native, always false
if frame is exception"
-
-#define f_set_is_native_doc "Usage: frame.is_natives(state)\n" \
- "state: boolean - set is_native to state"
-
-#define f_is_exception_doc "Usage: frame.is_exception()\n" \
- "Returns: boolean - true if frame is an exception"
-
-#define f_set_is_exception_doc "Usage: frame.is_exceptions(state)\n" \
- "state: boolean - set is_exception to state"
-
-#define f_get_message_doc "Usage: frame.get_message()\n" \
- "Returns: string - exception message"
-
-#define f_set_message_doc "Usage: frame.set_message(newexc)\n" \
- "newexc: string - new exception message"
+#define f_name_doc "Fully qualified domain name (string)"
+#define f_file_name_doc "File name (string)"
+#define f_file_line_doc "File line (positive integer)"
+#define f_class_path_doc "Class path (string)"
+#define f_native_doc "True if method is native, always false if frame is an
exception (bool)"
+#define f_exception_doc "True if frame is an exception frame (bool)"
+#define f_message_doc "Exception message (string)"
#define f_dup_doc "Usage: frame.dup()\n" \
"Returns: satyr.JavaFrame - a new clone of frame\n" \
@@ -86,27 +53,39 @@
static PyMethodDef
frame_methods[] =
{
- /* getters & setters */
- { "get_name", sr_py_java_frame_get_name,
METH_NOARGS, f_get_name_doc },
- { "set_name", sr_py_java_frame_set_name,
METH_VARARGS, f_set_name_doc },
- { "get_file_name", sr_py_java_frame_get_file_name,
METH_NOARGS, f_get_file_name_doc },
- { "set_file_name", sr_py_java_frame_set_file_name,
METH_VARARGS, f_set_file_name_doc },
- { "get_file_line", sr_py_java_frame_get_file_line,
METH_NOARGS, f_get_file_line_doc },
- { "set_file_line", sr_py_java_frame_set_file_line,
METH_VARARGS, f_set_file_line_doc },
- { "get_class_path", sr_py_java_frame_get_class_path,
METH_NOARGS, f_get_class_path_doc },
- { "set_class_path", sr_py_java_frame_set_class_path,
METH_VARARGS, f_set_class_path_doc },
- { "is_native", sr_py_java_frame_is_native,
METH_NOARGS, f_is_native_doc },
- { "set_is_native", sr_py_java_frame_set_is_native,
METH_VARARGS, f_set_is_native_doc },
- { "is_exception", sr_py_java_frame_is_exception,
METH_NOARGS, f_is_exception_doc },
- { "set_is_exception", sr_py_java_frame_set_is_exception,
METH_VARARGS, f_set_is_exception_doc },
- { "get_message", sr_py_java_frame_get_message,
METH_NOARGS, f_get_message_doc },
- { "set_message", sr_py_java_frame_set_message,
METH_VARARGS, f_set_message_doc },
/* methods */
- { "dup", sr_py_java_frame_dup,
METH_NOARGS, f_dup_doc },
- { "cmp", sr_py_java_frame_cmp,
METH_VARARGS, f_cmp_doc },
+ { "dup", sr_py_java_frame_dup, METH_NOARGS, f_dup_doc },
+ { "cmp", sr_py_java_frame_cmp, METH_VARARGS, f_cmp_doc },
{ NULL },
};
+/* See python/py_common.h and python/py_gdb_frame.c for generic getters/setters
documentation. */
+#define GSOFF_PY_STRUCT sr_py_java_frame
+#define GSOFF_PY_MEMBER frame
+#define GSOFF_C_STRUCT sr_java_frame
+GSOFF_START
+GSOFF_MEMBER(name),
+GSOFF_MEMBER(file_name),
+GSOFF_MEMBER(file_line),
+GSOFF_MEMBER(class_path),
+GSOFF_MEMBER(is_native),
+GSOFF_MEMBER(is_exception),
+GSOFF_MEMBER(message)
+GSOFF_END
+
+static PyGetSetDef
+frame_getset[] =
+{
+ { (char*)"name", sr_py_getter_string, sr_py_setter_string,
(char*)f_name_doc, &gsoff_name },
+ { (char*)"file_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_file_name_doc, &gsoff_file_name },
+ { (char*)"file_line", sr_py_getter_uint32, sr_py_setter_uint32,
(char*)f_file_line_doc, &gsoff_file_line },
+ { (char*)"class_path", sr_py_getter_string, sr_py_setter_string,
(char*)f_class_path_doc, &gsoff_class_path },
+ { (char*)"is_native", sr_py_getter_bool, sr_py_setter_bool,
(char*)f_native_doc, &gsoff_is_native },
+ { (char*)"is_exception", sr_py_getter_bool, sr_py_setter_bool,
(char*)f_exception_doc, &gsoff_is_exception },
+ { (char*)"message", sr_py_getter_string, sr_py_setter_string,
(char*)f_message_doc, &gsoff_message },
+ { NULL }
+};
+
PyTypeObject
sr_py_java_frame_type =
{
@@ -140,7 +119,7 @@ sr_py_java_frame_type =
NULL, /* tp_iternext */
frame_methods, /* tp_methods */
NULL, /* tp_members */
- NULL, /* tp_getset */
+ frame_getset, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
@@ -242,157 +221,6 @@ sr_py_java_frame_str(PyObject *self)
return result;
}
-/* getters & setters */
-
-/* name */
-PyObject *
-sr_py_java_frame_get_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_java_frame*)self)->frame->name);
-}
-
-PyObject *
-sr_py_java_frame_set_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_java_frame *frame = ((struct sr_py_java_frame*)self)->frame;
- free(frame->name);
- frame->name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* file_name */
-PyObject *
-sr_py_java_frame_get_file_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_java_frame*)self)->frame->file_name);
-}
-
-PyObject *
-sr_py_java_frame_set_file_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_java_frame *frame = ((struct sr_py_java_frame*)self)->frame;
- free(frame->file_name);
- frame->file_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* file_line */
-PyObject *
-sr_py_java_frame_get_file_line(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("i", ((struct
sr_py_java_frame*)self)->frame->file_line);
-}
-
-PyObject *
-sr_py_java_frame_set_file_line(PyObject *self, PyObject *args)
-{
- int newvalue;
- if (!PyArg_ParseTuple(args, "i", &newvalue))
- return NULL;
-
- if (newvalue < 0)
- {
- PyErr_SetString(PyExc_ValueError, "File line must not be negative.");
- return NULL;
- }
-
- struct sr_java_frame *frame = ((struct sr_py_java_frame*)self)->frame;
- frame->file_line = newvalue;
- Py_RETURN_NONE;
-}
-
-/* class_path */
-PyObject *
-sr_py_java_frame_get_class_path(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_java_frame*)self)->frame->class_path);
-}
-
-PyObject *
-sr_py_java_frame_set_class_path(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_java_frame *frame = ((struct sr_py_java_frame*)self)->frame;
- free(frame->class_path);
- frame->class_path = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* native */
-PyObject *
-sr_py_java_frame_is_native(PyObject *self, PyObject *args)
-{
- if (!((struct sr_py_java_frame*)self)->frame->is_native)
- Py_RETURN_FALSE;
-
- Py_RETURN_TRUE;
-}
-
-PyObject *
-sr_py_java_frame_set_is_native(PyObject *self, PyObject *args)
-{
- int boolvalue;
- if (!PyArg_ParseTuple(args, "i", &boolvalue))
- return NULL;
-
- struct sr_java_frame *frame = ((struct sr_py_java_frame*)self)->frame;
- frame->is_native = boolvalue;
- Py_RETURN_NONE;
-}
-
-/* exception */
-PyObject *
-sr_py_java_frame_is_exception(PyObject *self, PyObject *args)
-{
- if (!((struct sr_py_java_frame*)self)->frame->is_exception)
- Py_RETURN_FALSE;
-
- Py_RETURN_TRUE;
-}
-
-PyObject *
-sr_py_java_frame_set_is_exception(PyObject *self, PyObject *args)
-{
- int boolvalue;
- if (!PyArg_ParseTuple(args, "i", &boolvalue))
- return NULL;
-
- struct sr_java_frame *frame = ((struct sr_py_java_frame*)self)->frame;
- frame->is_exception = boolvalue;
- Py_RETURN_NONE;
-}
-
-/* message */
-PyObject *
-sr_py_java_frame_get_message(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_java_frame*)self)->frame->message);
-}
-
-PyObject *
-sr_py_java_frame_set_message(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_java_frame *frame = ((struct sr_py_java_frame*)self)->frame;
- free(frame->message);
- frame->message = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
/* methods */
PyObject *
sr_py_java_frame_dup(PyObject *self, PyObject *args)
diff --git a/python/py_java_frame.h b/python/py_java_frame.h
index a475acc..fead53a 100644
--- a/python/py_java_frame.h
+++ b/python/py_java_frame.h
@@ -56,22 +56,6 @@ void sr_py_java_frame_free(PyObject *object);
*/
PyObject *sr_py_java_frame_str(PyObject *self);
-/* getters & setters */
-PyObject *sr_py_java_frame_get_name(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_set_name(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_get_file_name(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_set_file_name(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_get_file_line(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_set_file_line(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_get_class_path(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_set_class_path(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_is_native(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_set_is_native(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_is_exception(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_set_is_exception(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_get_message(PyObject *self, PyObject *args);
-PyObject *sr_py_java_frame_set_message(PyObject *self, PyObject *args);
-
/* methods */
PyObject *sr_py_java_frame_dup(PyObject *self, PyObject *args);
PyObject *sr_py_java_frame_cmp(PyObject *self, PyObject *args);
diff --git a/python/py_java_thread.c b/python/py_java_thread.c
index b8f3452..4c926d6 100644
--- a/python/py_java_thread.c
+++ b/python/py_java_thread.c
@@ -1,3 +1,4 @@
+#include "py_common.h"
#include "py_java_thread.h"
#include "py_java_frame.h"
#include "lib/strbuf.h"
@@ -12,11 +13,7 @@
"satyr.JavaThread(str) - parses str and fills the thread
object\n" \
"satyr.JavaThread(str, only_funs=True) - parses list of function
names"
-#define t_get_name_doc "Usage: thread.get_name()\n" \
- "Returns: string - thread name"
-
-#define t_set_name_doc "Usage: thread.set_number(newname)\n" \
- "newname: string - new thread name"
+#define t_name_doc "Thread name (string)"
#define t_dup_doc "Usage: thread.dup()\n" \
"Returns: satyr.JavaThread - a new clone of thread\n" \
@@ -49,9 +46,6 @@
static PyMethodDef
java_thread_methods[] =
{
- /* getters & setters */
- { "get_number", sr_py_java_thread_get_name, METH_NOARGS,
t_get_name_doc },
- { "set_number", sr_py_java_thread_set_name, METH_VARARGS,
t_set_name_doc },
/* methods */
{ "cmp", sr_py_java_thread_cmp, METH_VARARGS,
t_cmp_doc },
{ "dup", sr_py_java_thread_dup, METH_NOARGS,
t_dup_doc },
@@ -68,6 +62,21 @@ java_thread_members[] =
{ NULL },
};
+/* See python/py_common.h and python/py_gdb_frame.c for generic getters/setters
documentation. */
+#define GSOFF_PY_STRUCT sr_py_java_thread
+#define GSOFF_PY_MEMBER thread
+#define GSOFF_C_STRUCT sr_java_thread
+GSOFF_START
+GSOFF_MEMBER(name)
+GSOFF_END
+
+static PyGetSetDef
+java_thread_getset[] =
+{
+ { (char*)"name", sr_py_getter_string, sr_py_setter_string,
(char*)t_name_doc, &gsoff_name },
+ { NULL },
+};
+
PyTypeObject sr_py_java_thread_type =
{
PyObject_HEAD_INIT(NULL)
@@ -100,7 +109,7 @@ PyTypeObject sr_py_java_thread_type =
NULL, /* tp_iternext */
java_thread_methods, /* tp_methods */
java_thread_members, /* tp_members */
- NULL, /* tp_getset */
+ java_thread_getset, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
@@ -271,29 +280,6 @@ sr_py_java_thread_str(PyObject *self)
return result;
}
-/* getters & setters */
-
-/* name */
-PyObject *
-sr_py_java_thread_get_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_java_thread*)self)->thread->name);
-}
-
-PyObject *
-sr_py_java_thread_set_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_java_thread *thread = ((struct sr_py_java_thread*)self)->thread;
- free(thread->name);
- thread->name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-
/* methods */
PyObject *
sr_py_java_thread_dup(PyObject *self, PyObject *args)
diff --git a/python/py_java_thread.h b/python/py_java_thread.h
index 7d347e5..a0754c5 100644
--- a/python/py_java_thread.h
+++ b/python/py_java_thread.h
@@ -57,10 +57,6 @@ void sr_py_java_thread_free(PyObject *object);
/* str */
PyObject *sr_py_java_thread_str(PyObject *self);
-/* getters & setters */
-PyObject *sr_py_java_thread_get_name(PyObject *self, PyObject *args);
-PyObject *sr_py_java_thread_set_name(PyObject *self, PyObject *args);
-
/* methods */
PyObject *sr_py_java_thread_dup(PyObject *self, PyObject *args);
PyObject *sr_py_java_thread_cmp(PyObject *self, PyObject *args);
diff --git a/python/py_koops_frame.c b/python/py_koops_frame.c
index e6dad1e..cf6a835 100644
--- a/python/py_koops_frame.c
+++ b/python/py_koops_frame.c
@@ -17,6 +17,7 @@
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "py_common.h"
#include "py_koops_frame.h"
#include <inttypes.h>
@@ -31,74 +32,17 @@
"satyr.KerneloopsFrame() - creates an empty frame\n" \
"satyr.KerneloopsFrame(str) - parses str and fills the frame
object"
-#define f_get_reliable_doc "Usage: frame.get_reliable()\n" \
- "Returns: boolean - is this entry reliable"
-
-#define f_set_reliable_doc "Usage: frame.set_address(state)\n" \
- "state: boolean - set reliability to state"
-
-#define f_get_address_doc "Usage: frame.get_address()\n" \
- "Returns: positive long integer - address"
-
-#define f_set_address_doc "Usage: frame.set_address(N)\n" \
- "N: positive long integer - new address"
-
-#define f_get_function_name_doc "Usage: frame.get_function_name()\n" \
- "Returns: string - function name"
-
-#define f_set_function_name_doc "Usage: frame.set_function_name(newname)\n" \
- "newname: string - new function name"
-
-#define f_get_function_offset_doc "Usage: frame.get_function_offset()\n" \
- "Returns: positive long integer - function
offset"
-
-#define f_set_function_offset_doc "Usage:
frame.set_function_offset(newoffset)\n" \
- "newoffset: positive long integer - new function
offset"
-
-#define f_get_function_length_doc "Usage: frame.get_function_length()\n" \
- "Returns: positive long integer - function
length"
-
-#define f_set_function_length_doc "Usage:
frame.set_function_length(newlength)\n" \
- "newlength: positive long integer - new function
length"
-
-#define f_get_module_name_doc "Usage: frame.get_module_name()\n" \
- "Returns: string - module name"
-
-#define f_set_module_name_doc "Usage: frame.set_module_name(newname)\n" \
- "newname: string - new module name"
-
-
-
-#define f_get_from_address_doc "Usage: frame.get_from_address()\n" \
- "Returns: positive long integer - from address"
-
-#define f_set_from_address_doc "Usage: frame.set_from_address(N)\n" \
- "N: positive long integer - new from address"
-
-#define f_get_from_function_name_doc "Usage: frame.get_from_function_name()\n"
\
- "Returns: string - from function name"
-
-#define f_set_from_function_name_doc "Usage:
frame.set_from_function_name(newname)\n" \
- "newname: string - new from function name"
-
-#define f_get_from_function_offset_doc "Usage:
frame.get_from_function_offset()\n" \
- "Returns: positive long integer - from function
offset"
-
-#define f_set_from_function_offset_doc "Usage:
frame.set_from_function_offset(newoffset)\n" \
- "newoffset: positive long integer - new from
function offset"
-
-#define f_get_from_function_length_doc "Usage:
frame.get_from_function_length()\n" \
- "Returns: positive long integer - from function
length"
-
-#define f_set_from_function_length_doc "Usage:
frame.set_from_function_length(newlength)\n" \
- "newlength: positive long integer - new from
function length"
-
-#define f_get_from_module_name_doc "Usage: frame.get_from_module_name()\n" \
- "Returns: string - from module name"
-
-#define f_set_from_module_name_doc "Usage:
frame.set_from_module_name(newname)\n" \
- "newname: string - new from module name"
-
+#define f_reliable_doc "True if the the frame is guaranteed to be real
(bool)"
+#define f_address_doc "Address of the current instruction (long)"
+#define f_function_name_doc "Function name (string)"
+#define f_function_offset_doc "Function offset (long)"
+#define f_function_length_doc "Function length (long)"
+#define f_module_name_doc "Module owning the function (string)"
+#define f_from_address_doc "Address of the caller's instruction
(long)"
+#define f_from_function_name_doc "Caller function name (string)"
+#define f_from_function_offset_doc "Caller function offset (long)"
+#define f_from_function_length_doc "Caller function length (long)"
+#define f_from_module_name_doc "Module owning the caller function
(string)"
#define f_dup_doc "Usage: frame.dup()\n" \
"Returns: satyr.KerneloopsFrame - a new clone of frame\n" \
@@ -116,36 +60,47 @@
static PyMethodDef
frame_methods[] =
{
- /* getters & setters */
- { "get_reliable", sr_py_koops_frame_get_reliable,
METH_NOARGS, f_get_reliable_doc },
- { "set_reliable", sr_py_koops_frame_set_reliable,
METH_VARARGS, f_set_reliable_doc },
- { "get_address", sr_py_koops_frame_get_address,
METH_NOARGS, f_get_address_doc },
- { "set_address", sr_py_koops_frame_set_address,
METH_VARARGS, f_set_address_doc },
- { "get_function_name", sr_py_koops_frame_get_function_name,
METH_NOARGS, f_get_function_name_doc },
- { "set_function_name", sr_py_koops_frame_set_function_name,
METH_VARARGS, f_set_function_name_doc },
- { "get_function_offset", sr_py_koops_frame_get_function_offset,
METH_NOARGS, f_get_function_offset_doc },
- { "set_function_offset", sr_py_koops_frame_set_function_offset,
METH_VARARGS, f_set_function_offset_doc },
- { "get_function_length", sr_py_koops_frame_get_function_length,
METH_NOARGS, f_get_function_length_doc },
- { "set_function_length", sr_py_koops_frame_set_function_length,
METH_VARARGS, f_set_function_length_doc },
- { "get_module_name", sr_py_koops_frame_get_module_name,
METH_NOARGS, f_get_module_name_doc },
- { "set_module_name", sr_py_koops_frame_set_module_name,
METH_VARARGS, f_set_module_name_doc },
- { "get_from_address", sr_py_koops_frame_get_from_address,
METH_NOARGS, f_get_from_address_doc },
- { "set_from_address", sr_py_koops_frame_set_from_address,
METH_VARARGS, f_set_from_address_doc },
- { "get_from_function_name", sr_py_koops_frame_get_from_function_name,
METH_NOARGS, f_get_from_function_name_doc },
- { "set_from_function_name", sr_py_koops_frame_set_from_function_name,
METH_VARARGS, f_set_from_function_name_doc },
- { "get_from_function_offset", sr_py_koops_frame_get_from_function_offset,
METH_NOARGS, f_get_from_function_offset_doc },
- { "set_from_function_offset", sr_py_koops_frame_set_from_function_offset,
METH_VARARGS, f_set_from_function_offset_doc },
- { "get_from_function_length", sr_py_koops_frame_get_from_function_length,
METH_NOARGS, f_get_from_function_length_doc },
- { "set_from_function_length", sr_py_koops_frame_set_from_function_length,
METH_VARARGS, f_set_from_function_length_doc },
- { "get_from_module_name", sr_py_koops_frame_get_from_module_name,
METH_NOARGS, f_get_from_module_name_doc },
- { "set_from_module_name", sr_py_koops_frame_set_from_module_name,
METH_VARARGS, f_set_from_module_name_doc },
-
/* methods */
{ "dup", sr_py_koops_frame_dup,
METH_NOARGS, f_dup_doc },
{ "cmp", sr_py_koops_frame_cmp,
METH_VARARGS, f_cmp_doc },
{ NULL },
};
+/* See python/py_common.h and python/py_gdb_frame.c for generic getters/setters
documentation. */
+#define GSOFF_PY_STRUCT sr_py_koops_frame
+#define GSOFF_PY_MEMBER frame
+#define GSOFF_C_STRUCT sr_koops_frame
+GSOFF_START
+GSOFF_MEMBER(address),
+GSOFF_MEMBER(reliable),
+GSOFF_MEMBER(function_name),
+GSOFF_MEMBER(function_offset),
+GSOFF_MEMBER(function_length),
+GSOFF_MEMBER(module_name),
+GSOFF_MEMBER(from_address),
+GSOFF_MEMBER(from_function_name),
+GSOFF_MEMBER(from_function_offset),
+GSOFF_MEMBER(from_function_length),
+GSOFF_MEMBER(from_module_name)
+GSOFF_END
+
+static PyGetSetDef
+frame_getset[] =
+{
+ { (char*)"reliable", sr_py_getter_bool, sr_py_setter_bool,
(char*)f_reliable_doc, &gsoff_reliable },
+ { (char*)"address", sr_py_getter_uint64, sr_py_setter_uint64,
(char*)f_address_doc, &gsoff_address },
+ { (char*)"function_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_function_name_doc, &gsoff_function_name },
+ { (char*)"function_offset", sr_py_getter_uint64, sr_py_setter_uint64,
(char*)f_function_offset_doc, &gsoff_function_offset },
+ { (char*)"function_length", sr_py_getter_uint64, sr_py_setter_uint64,
(char*)f_function_length_doc, &gsoff_function_length },
+ { (char*)"module_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_module_name_doc, &gsoff_module_name },
+ { (char*)"from_address", sr_py_getter_uint64, sr_py_setter_uint64,
(char*)f_from_address_doc, &gsoff_from_address },
+ { (char*)"from_function_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_from_function_name_doc, &gsoff_from_function_name },
+ { (char*)"from_function_offset", sr_py_getter_uint64, sr_py_setter_uint64,
(char*)f_from_function_offset_doc, &gsoff_from_function_offset },
+ { (char*)"from_function_length", sr_py_getter_uint64, sr_py_setter_uint64,
(char*)f_from_function_length_doc, &gsoff_from_function_length },
+ { (char*)"from_module_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_from_module_name_doc, &gsoff_from_module_name },
+ { NULL },
+};
+
PyTypeObject
sr_py_koops_frame_type =
{
@@ -179,7 +134,7 @@ sr_py_koops_frame_type =
NULL, /* tp_iternext */
frame_methods, /* tp_methods */
NULL, /* tp_members */
- NULL, /* tp_getset */
+ frame_getset, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
@@ -278,231 +233,6 @@ sr_py_koops_frame_str(PyObject *self)
return result;
}
-/* getters & setters */
-
-/* reliable */
-PyObject *
-sr_py_koops_frame_get_reliable(PyObject *self, PyObject *args)
-{
- if (!((struct sr_py_koops_frame*)self)->frame->reliable)
- Py_RETURN_FALSE;
-
- Py_RETURN_TRUE;
-}
-
-PyObject *
-sr_py_koops_frame_set_reliable(PyObject *self, PyObject *args)
-{
- int boolvalue;
- if (!PyArg_ParseTuple(args, "i", &boolvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- frame->reliable = boolvalue;
- Py_RETURN_NONE;
-}
-
-/* address */
-PyObject *
-sr_py_koops_frame_get_address(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("K",
- (unsigned long long)(((struct sr_py_koops_frame*)self)->frame->address));
-}
-
-PyObject *
-sr_py_koops_frame_set_address(PyObject *self, PyObject *args)
-{
- unsigned long long newvalue;
- if (!PyArg_ParseTuple(args, "K", &newvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- frame->address = newvalue;
- Py_RETURN_NONE;
-}
-
-/* from_address */
-PyObject *
-sr_py_koops_frame_get_from_address(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("K",
- (unsigned long long)(((struct
sr_py_koops_frame*)self)->frame->from_address));
-}
-
-PyObject *
-sr_py_koops_frame_set_from_address(PyObject *self, PyObject *args)
-{
- unsigned long long newvalue;
- if (!PyArg_ParseTuple(args, "K", &newvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- frame->from_address = newvalue;
- Py_RETURN_NONE;
-}
-
-
-/* function_name */
-PyObject *
-sr_py_koops_frame_get_function_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_koops_frame*)self)->frame->function_name);
-}
-
-PyObject *
-sr_py_koops_frame_set_function_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- free(frame->function_name);
- frame->function_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* from_function_name */
-PyObject *
-sr_py_koops_frame_get_from_function_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_koops_frame*)self)->frame->from_function_name);
-}
-
-PyObject *
-sr_py_koops_frame_set_from_function_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- free(frame->function_name);
- frame->from_function_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* function_offset */
-PyObject *
-sr_py_koops_frame_get_function_offset(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("K",
- (unsigned long long)(((struct
sr_py_koops_frame*)self)->frame->function_offset));
-}
-
-PyObject *
-sr_py_koops_frame_set_function_offset(PyObject *self, PyObject *args)
-{
- unsigned long long newvalue;
- if (!PyArg_ParseTuple(args, "K", &newvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- frame->function_offset = newvalue;
- Py_RETURN_NONE;
-}
-
-/* from_function_offset */
-PyObject *
-sr_py_koops_frame_get_from_function_offset(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("K",
- (unsigned long long)(((struct
sr_py_koops_frame*)self)->frame->from_function_offset));
-}
-
-PyObject *
-sr_py_koops_frame_set_from_function_offset(PyObject *self, PyObject *args)
-{
- unsigned long long newvalue;
- if (!PyArg_ParseTuple(args, "K", &newvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- frame->from_function_offset = newvalue;
- Py_RETURN_NONE;
-}
-
-/* function_length */
-PyObject *
-sr_py_koops_frame_get_function_length(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("K",
- (unsigned long long)(((struct
sr_py_koops_frame*)self)->frame->function_length));
-}
-
-PyObject *
-sr_py_koops_frame_set_function_length(PyObject *self, PyObject *args)
-{
- unsigned long long newvalue;
- if (!PyArg_ParseTuple(args, "K", &newvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- frame->function_length = newvalue;
- Py_RETURN_NONE;
-}
-
-/* from_function_length */
-PyObject *
-sr_py_koops_frame_get_from_function_length(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("K",
- (unsigned long long)(((struct
sr_py_koops_frame*)self)->frame->from_function_length));
-}
-
-PyObject *
-sr_py_koops_frame_set_from_function_length(PyObject *self, PyObject *args)
-{
- unsigned long long newvalue;
- if (!PyArg_ParseTuple(args, "K", &newvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- frame->from_function_length = newvalue;
- Py_RETURN_NONE;
-}
-
-/* module_name */
-PyObject *
-sr_py_koops_frame_get_module_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_koops_frame*)self)->frame->module_name);
-}
-
-PyObject *
-sr_py_koops_frame_set_module_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- free(frame->module_name);
- frame->module_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* from_module_name */
-PyObject *
-sr_py_koops_frame_get_from_module_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_koops_frame*)self)->frame->from_module_name);
-}
-
-PyObject *
-sr_py_koops_frame_set_from_module_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_koops_frame *frame = ((struct sr_py_koops_frame*)self)->frame;
- free(frame->module_name);
- frame->from_module_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
/* methods */
PyObject *
sr_py_koops_frame_dup(PyObject *self, PyObject *args)
diff --git a/python/py_koops_frame.h b/python/py_koops_frame.h
index 51dc4d9..e9c13f5 100644
--- a/python/py_koops_frame.h
+++ b/python/py_koops_frame.h
@@ -56,31 +56,6 @@ void sr_py_koops_frame_free(PyObject *object);
*/
PyObject *sr_py_koops_frame_str(PyObject *self);
-/* getters & setters */
-PyObject *sr_py_koops_frame_get_reliable(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_reliable(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_get_address(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_address(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_get_function_name(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_function_name(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_get_function_offset(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_function_offset(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_get_function_length(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_function_length(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_get_module_name(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_module_name(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_get_from_address(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_from_address(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_get_from_function_name(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_from_function_name(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_get_from_function_offset(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_from_function_offset(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_get_from_function_length(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_from_function_length(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_get_from_module_name(PyObject *self, PyObject *args);
-PyObject *sr_py_koops_frame_set_from_module_name(PyObject *self, PyObject *args);
-
-
/* methods */
PyObject *sr_py_koops_frame_dup(PyObject *self, PyObject *args);
PyObject *sr_py_koops_frame_cmp(PyObject *self, PyObject *args);
diff --git a/python/py_koops_stacktrace.c b/python/py_koops_stacktrace.c
index fcb367e..cd74fd9 100644
--- a/python/py_koops_stacktrace.c
+++ b/python/py_koops_stacktrace.c
@@ -20,15 +20,12 @@
"Normalizes the stacktrace."
#define b_frames_doc "A list containing frames"
-#define b_get_modules_doc "Usage: stacktrace.get_modules()\n" \
- "Returns: list of strings - loaded modules at time of the
event"
+#define b_modules_doc "Modules loaded at the time of the event (list of
strings)"
static PyMethodDef
koops_stacktrace_methods[] =
{
- /* getters & setters */
- { "get_modules", sr_py_koops_stacktrace_get_modules,
METH_NOARGS, b_get_modules_doc },
/* methods */
{ "dup", sr_py_koops_stacktrace_dup,
METH_NOARGS, b_dup_doc },
{ "normalize", sr_py_koops_stacktrace_normalize,
METH_NOARGS, b_normalize_doc },
@@ -42,6 +39,13 @@ koops_stacktrace_members[] =
{ NULL },
};
+static PyGetSetDef
+koops_stacktrace_getset[] =
+{
+ { (char*)"modules", sr_py_koops_stacktrace_get_modules,
sr_py_koops_stacktrace_set_modules, (char*)b_modules_doc, NULL },
+ { NULL },
+};
+
PyTypeObject sr_py_koops_stacktrace_type = {
PyObject_HEAD_INIT(NULL)
0,
@@ -73,7 +77,7 @@ PyTypeObject sr_py_koops_stacktrace_type = {
NULL, /* tp_iternext */
koops_stacktrace_methods, /* tp_methods */
koops_stacktrace_members, /* tp_members */
- NULL, /* tp_getset */
+ koops_stacktrace_getset, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
@@ -135,7 +139,7 @@ koops_stacktrace_prepare_linked_list(struct sr_py_koops_stacktrace
*stacktrace)
}
PyObject *
-sr_py_koops_stacktrace_get_modules(PyObject *self, PyObject *args)
+sr_py_koops_stacktrace_get_modules(PyObject *self, void *data)
{
struct sr_koops_stacktrace *st = ((struct
sr_py_koops_stacktrace*)self)->stacktrace;
char **iter = st->modules;
@@ -152,6 +156,13 @@ sr_py_koops_stacktrace_get_modules(PyObject *self, PyObject *args)
return result;
}
+int
+sr_py_koops_stacktrace_set_modules(PyObject *self, PyObject *rhs, void *data)
+{
+ PyErr_SetString(PyExc_NotImplementedError, "Setting module list is not
implemented.");
+ return -1;
+}
+
PyObject *
koops_frame_linked_list_to_python_list(struct sr_koops_stacktrace *stacktrace)
{
diff --git a/python/py_koops_stacktrace.h b/python/py_koops_stacktrace.h
index 6c4ce89..b36b555 100644
--- a/python/py_koops_stacktrace.h
+++ b/python/py_koops_stacktrace.h
@@ -53,7 +53,8 @@ void sr_py_koops_stacktrace_free(PyObject *object);
PyObject *sr_py_koops_stacktrace_str(PyObject *self);
/* getters & setters */
-PyObject *sr_py_koops_stacktrace_get_modules(PyObject *self, PyObject *args);
+PyObject *sr_py_koops_stacktrace_get_modules(PyObject *self, void *data);
+int sr_py_koops_stacktrace_set_modules(PyObject *self, PyObject *rhs, void *data);
/* methods */
PyObject *sr_py_koops_stacktrace_dup(PyObject *self, PyObject *args);
diff --git a/python/py_module.c b/python/py_module.c
index e48718e..4eb3505 100644
--- a/python/py_module.c
+++ b/python/py_module.c
@@ -13,6 +13,8 @@
#include "py_java_stacktrace.h"
#include "py_metrics.h"
+#include "lib/gdb_sharedlib.h"
+
static PyMethodDef
module_methods[]=
{
@@ -136,6 +138,10 @@ init_satyr()
PyModule_AddObject(module, "GdbSharedlib",
(PyObject *)&sr_py_gdb_sharedlib_type);
+ PyModule_AddIntMacro(module, SYMS_OK);
+ PyModule_AddIntMacro(module, SYMS_NOT_FOUND);
+ PyModule_AddIntMacro(module, SYMS_WRONG);
+
Py_INCREF(&sr_py_koops_frame_type);
PyModule_AddObject(module, "KerneloopsFrame",
(PyObject *)&sr_py_koops_frame_type);
diff --git a/python/py_python_frame.c b/python/py_python_frame.c
index 0cf16cb..79098c2 100644
--- a/python/py_python_frame.c
+++ b/python/py_python_frame.c
@@ -17,6 +17,7 @@
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "py_common.h"
#include "py_python_frame.h"
#include "lib/location.h"
#include "lib/strbuf.h"
@@ -28,35 +29,11 @@
"satyr.PythonFrame() - creates an empty frame\n" \
"satyr.PythonFrame(str) - parses str and fills the frame
object"
-#define f_get_file_name_doc "Usage: frame.get_file_name()\n" \
- "Returns: string - file name"
-
-#define f_set_file_name_doc "Usage: frame.set_file_name(newname)\n" \
- "newname: string - new file name"
-
-#define f_get_file_line_doc "Usage: frame.get_file_line()\n" \
- "Returns: unsigned int - file line"
-
-#define f_set_file_line_doc "Usage: frame.set_file_line(newline)\n" \
- "newline: unsigned int - new file line"
-
-#define f_is_module_doc "Usage: frame.is_module()\n" \
- "Returns: boolean - is this entry from main module"
-
-#define f_set_is_module_doc "Usage: frame.is_modules(state)\n" \
- "state: boolean - set is_module to state"
-
-#define f_get_function_name_doc "Usage: frame.get_function_name()\n" \
- "Returns: string - function name"
-
-#define f_set_function_name_doc "Usage: frame.set_function_name(newname)\n" \
- "newname: string - new function name"
-
-#define f_get_line_contents_doc "Usage: frame.get_line_contents()\n" \
- "Returns: string - remaining line contents"
-
-#define f_set_line_contents_doc "Usage: frame.set_line_contents(newname)\n" \
- "newname: string - new line contents"
+#define f_file_name_doc "Source file name (string)"
+#define f_file_line_doc "Source line number (positive integer)"
+#define f_is_module_doc "True if the frame is from the main module (bool)"
+#define f_function_name_doc "Function name (string)"
+#define f_line_contents_doc "Remaining line contents (string)"
#define f_dup_doc "Usage: frame.dup()\n" \
"Returns: satyr.PythonFrame - a new clone of frame\n" \
@@ -74,20 +51,32 @@
static PyMethodDef
frame_methods[] =
{
- /* getters & setters */
- { "get_file_name", sr_py_python_frame_get_file_name,
METH_NOARGS, f_get_file_name_doc },
- { "set_file_name", sr_py_python_frame_set_file_name,
METH_VARARGS, f_set_file_name_doc },
- { "get_file_line", sr_py_python_frame_get_file_line,
METH_NOARGS, f_get_file_line_doc },
- { "set_file_line", sr_py_python_frame_set_file_line,
METH_VARARGS, f_set_file_line_doc },
- { "is_module", sr_py_python_frame_is_module,
METH_NOARGS, f_is_module_doc },
- { "set_is_module", sr_py_python_frame_set_is_module,
METH_VARARGS, f_set_is_module_doc },
- { "get_function_name", sr_py_python_frame_get_function_name,
METH_NOARGS, f_get_function_name_doc },
- { "set_function_name", sr_py_python_frame_set_function_name,
METH_VARARGS, f_set_function_name_doc },
- { "get_line_contents", sr_py_python_frame_get_line_contents,
METH_NOARGS, f_get_line_contents_doc },
- { "set_line_contents", sr_py_python_frame_set_line_contents,
METH_VARARGS, f_set_line_contents_doc },
/* methods */
- { "dup", sr_py_python_frame_dup,
METH_NOARGS, f_dup_doc },
- { "cmp", sr_py_python_frame_cmp,
METH_VARARGS, f_cmp_doc },
+ { "dup", sr_py_python_frame_dup, METH_NOARGS, f_dup_doc },
+ { "cmp", sr_py_python_frame_cmp, METH_VARARGS, f_cmp_doc },
+ { NULL },
+};
+
+/* See python/py_common.h and python/py_gdb_frame.c for generic getters/setters
documentation. */
+#define GSOFF_PY_STRUCT sr_py_python_frame
+#define GSOFF_PY_MEMBER frame
+#define GSOFF_C_STRUCT sr_python_frame
+GSOFF_START
+GSOFF_MEMBER(file_name),
+GSOFF_MEMBER(file_line),
+GSOFF_MEMBER(is_module),
+GSOFF_MEMBER(function_name),
+GSOFF_MEMBER(line_contents)
+GSOFF_END
+
+static PyGetSetDef
+frame_getset[] =
+{
+ { (char*)"file_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_file_name_doc, &gsoff_file_name },
+ { (char*)"file_line", sr_py_getter_uint32, sr_py_setter_uint32,
(char*)f_file_line_doc, &gsoff_file_line },
+ { (char*)"is_module", sr_py_getter_bool, sr_py_setter_bool,
(char*)f_is_module_doc, &gsoff_is_module },
+ { (char*)"function_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_function_name_doc, &gsoff_function_name },
+ { (char*)"line_contents", sr_py_getter_string, sr_py_setter_string,
(char*)f_line_contents_doc, &gsoff_line_contents },
{ NULL },
};
@@ -124,7 +113,7 @@ sr_py_python_frame_type =
NULL, /* tp_iternext */
frame_methods, /* tp_methods */
NULL, /* tp_members */
- NULL, /* tp_getset */
+ frame_getset, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
@@ -212,115 +201,6 @@ sr_py_python_frame_str(PyObject *self)
return result;
}
-/* getters & setters */
-
-/* file_name */
-PyObject *
-sr_py_python_frame_get_file_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_python_frame*)self)->frame->file_name);
-}
-
-PyObject *
-sr_py_python_frame_set_file_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_python_frame *frame = ((struct sr_py_python_frame*)self)->frame;
- free(frame->file_name);
- frame->file_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* file_line */
-PyObject *
-sr_py_python_frame_get_file_line(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("i", ((struct
sr_py_python_frame*)self)->frame->file_line);
-}
-
-PyObject *
-sr_py_python_frame_set_file_line(PyObject *self, PyObject *args)
-{
- int newvalue;
- if (!PyArg_ParseTuple(args, "i", &newvalue))
- return NULL;
-
- if (newvalue < 0)
- {
- PyErr_SetString(PyExc_ValueError, "File line must not be negative.");
- return NULL;
- }
-
- struct sr_python_frame *frame = ((struct sr_py_python_frame*)self)->frame;
- frame->file_line = newvalue;
- Py_RETURN_NONE;
-}
-
-/* reliable */
-PyObject *
-sr_py_python_frame_is_module(PyObject *self, PyObject *args)
-{
- if (!((struct sr_py_python_frame*)self)->frame->is_module)
- Py_RETURN_FALSE;
-
- Py_RETURN_TRUE;
-}
-
-PyObject *
-sr_py_python_frame_set_is_module(PyObject *self, PyObject *args)
-{
- int boolvalue;
- if (!PyArg_ParseTuple(args, "i", &boolvalue))
- return NULL;
-
- struct sr_python_frame *frame = ((struct sr_py_python_frame*)self)->frame;
- frame->is_module = boolvalue;
- Py_RETURN_NONE;
-}
-
-/* function_name */
-PyObject *
-sr_py_python_frame_get_function_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_python_frame*)self)->frame->function_name);
-}
-
-PyObject *
-sr_py_python_frame_set_function_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_python_frame *frame = ((struct sr_py_python_frame*)self)->frame;
- free(frame->function_name);
- frame->function_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* line_contents */
-PyObject *
-sr_py_python_frame_get_line_contents(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_python_frame*)self)->frame->line_contents);
-}
-
-PyObject *
-sr_py_python_frame_set_line_contents(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_python_frame *frame = ((struct sr_py_python_frame*)self)->frame;
- free(frame->line_contents);
- frame->line_contents = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
/* methods */
PyObject *
sr_py_python_frame_dup(PyObject *self, PyObject *args)
diff --git a/python/py_python_frame.h b/python/py_python_frame.h
index 95df450..f0848c2 100644
--- a/python/py_python_frame.h
+++ b/python/py_python_frame.h
@@ -56,18 +56,6 @@ void sr_py_python_frame_free(PyObject *object);
*/
PyObject *sr_py_python_frame_str(PyObject *self);
-/* getters & setters */
-PyObject *sr_py_python_frame_get_file_name(PyObject *self, PyObject *args);
-PyObject *sr_py_python_frame_set_file_name(PyObject *self, PyObject *args);
-PyObject *sr_py_python_frame_get_file_line(PyObject *self, PyObject *args);
-PyObject *sr_py_python_frame_set_file_line(PyObject *self, PyObject *args);
-PyObject *sr_py_python_frame_is_module(PyObject *self, PyObject *args);
-PyObject *sr_py_python_frame_set_is_module(PyObject *self, PyObject *args);
-PyObject *sr_py_python_frame_get_function_name(PyObject *self, PyObject *args);
-PyObject *sr_py_python_frame_set_function_name(PyObject *self, PyObject *args);
-PyObject *sr_py_python_frame_get_line_contents(PyObject *self, PyObject *args);
-PyObject *sr_py_python_frame_set_line_contents(PyObject *self, PyObject *args);
-
/* methods */
PyObject *sr_py_python_frame_dup(PyObject *self, PyObject *args);
PyObject *sr_py_python_frame_cmp(PyObject *self, PyObject *args);
diff --git a/python/py_python_stacktrace.c b/python/py_python_stacktrace.c
index 92af646..a0a5141 100644
--- a/python/py_python_stacktrace.c
+++ b/python/py_python_stacktrace.c
@@ -1,3 +1,4 @@
+#include "py_common.h"
#include "py_python_frame.h"
#include "py_python_stacktrace.h"
#include "lib/utils.h"
@@ -12,23 +13,9 @@
"satyr.PythonStacktrace() - creates an empty python
stacktrace\n" \
"satyr.PythonStacktrace(str) - parses str and fills the python
stacktrace object"
-#define f_get_file_name_doc "Usage: frame.get_file_name()\n" \
- "Returns: string - file name"
-
-#define f_set_file_name_doc "Usage: frame.set_file_name(newname)\n" \
- "newname: string - new file name"
-
-#define f_get_file_line_doc "Usage: frame.get_file_line()\n" \
- "Returns: unsigned int - file line"
-
-#define f_set_file_line_doc "Usage: frame.set_file_line(newline)\n" \
- "newline: unsigned int - new file line"
-
-#define f_get_exception_name_doc "Usage: frame.get_exception_name()\n" \
- "Returns: string - function name"
-
-#define f_set_exception_name_doc "Usage: frame.set_exception_name(newname)\n"
\
- "newname: string - new function name"
+#define f_file_name_doc "Source file name (string)"
+#define f_file_line_doc "Source line number (positive integer)"
+#define f_exception_name_doc "Exception type (string)"
#define f_dup_doc "Usage: stacktrace.dup()\n" \
"Returns: satyr.PythonStacktrace - a new clone of python
stacktrace\n" \
@@ -46,16 +33,9 @@
static PyMethodDef
python_stacktrace_methods[] =
{
- /* getters & setters */
- { "get_file_name", sr_py_python_stacktrace_get_file_name,
METH_NOARGS, f_get_file_name_doc },
- { "set_file_name", sr_py_python_stacktrace_set_file_name,
METH_VARARGS, f_set_file_name_doc },
- { "get_file_line", sr_py_python_stacktrace_get_file_line,
METH_NOARGS, f_get_file_line_doc },
- { "set_file_line", sr_py_python_stacktrace_set_file_line,
METH_VARARGS, f_set_file_line_doc },
- { "get_exception_name", sr_py_python_stacktrace_get_exception_name,
METH_NOARGS, f_get_exception_name_doc },
- { "set_exception_name", sr_py_python_stacktrace_set_exception_name,
METH_VARARGS, f_set_exception_name_doc },
/* methods */
- { "dup", sr_py_python_stacktrace_dup,
METH_NOARGS, f_dup_doc },
-// { "normalize", sr_py_python_stacktrace_normalize,
METH_NOARGS, f_normalize_doc },
+ { "dup", sr_py_python_stacktrace_dup, METH_NOARGS, f_dup_doc },
+// { "normalize", sr_py_python_stacktrace_normalize, METH_NOARGS,
f_normalize_doc },
{ NULL },
};
@@ -66,6 +46,25 @@ python_stacktrace_members[] =
{ NULL },
};
+/* See python/py_common.h and python/py_gdb_frame.c for generic getters/setters
documentation. */
+#define GSOFF_PY_STRUCT sr_py_python_stacktrace
+#define GSOFF_PY_MEMBER stacktrace
+#define GSOFF_C_STRUCT sr_python_stacktrace
+GSOFF_START
+GSOFF_MEMBER(file_name),
+GSOFF_MEMBER(file_line),
+GSOFF_MEMBER(exception_name)
+GSOFF_END
+
+static PyGetSetDef
+python_stacktrace_getset[] =
+{
+ { (char*)"file_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_file_name_doc, &gsoff_file_name },
+ { (char*)"file_line", sr_py_getter_uint32, sr_py_setter_uint32,
(char*)f_file_line_doc, &gsoff_file_line },
+ { (char*)"exception_name", sr_py_getter_string, sr_py_setter_string,
(char*)f_exception_name_doc, &gsoff_exception_name },
+ { NULL },
+};
+
PyTypeObject sr_py_python_stacktrace_type = {
PyObject_HEAD_INIT(NULL)
0,
@@ -97,7 +96,7 @@ PyTypeObject sr_py_python_stacktrace_type = {
NULL, /* tp_iternext */
python_stacktrace_methods, /* tp_methods */
python_stacktrace_members, /* tp_members */
- NULL, /* tp_getset */
+ python_stacktrace_getset, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
@@ -268,73 +267,6 @@ sr_py_python_stacktrace_str(PyObject *self)
return result;
}
-/* getters & setters */
-
-/* file_name */
-PyObject *
-sr_py_python_stacktrace_get_file_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_python_stacktrace*)self)->stacktrace->file_name);
-}
-
-PyObject *
-sr_py_python_stacktrace_set_file_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_python_stacktrace *stacktrace = ((struct
sr_py_python_stacktrace*)self)->stacktrace;
- free(stacktrace->file_name);
- stacktrace->file_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
-/* file_line */
-PyObject *
-sr_py_python_stacktrace_get_file_line(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("i", ((struct
sr_py_python_stacktrace*)self)->stacktrace->file_line);
-}
-
-PyObject *
-sr_py_python_stacktrace_set_file_line(PyObject *self, PyObject *args)
-{
- int newvalue;
- if (!PyArg_ParseTuple(args, "i", &newvalue))
- return NULL;
-
- if (newvalue < 0)
- {
- PyErr_SetString(PyExc_ValueError, "File line must not be negative.");
- return NULL;
- }
-
- struct sr_python_stacktrace *stacktrace = ((struct
sr_py_python_stacktrace*)self)->stacktrace;
- stacktrace->file_line = newvalue;
- Py_RETURN_NONE;
-}
-
-/* exception_name */
-PyObject *
-sr_py_python_stacktrace_get_exception_name(PyObject *self, PyObject *args)
-{
- return Py_BuildValue("s", ((struct
sr_py_python_stacktrace*)self)->stacktrace->exception_name);
-}
-
-PyObject *
-sr_py_python_stacktrace_set_exception_name(PyObject *self, PyObject *args)
-{
- char *newvalue;
- if (!PyArg_ParseTuple(args, "s", &newvalue))
- return NULL;
-
- struct sr_python_stacktrace *stacktrace = ((struct
sr_py_python_stacktrace*)self)->stacktrace;
- free(stacktrace->file_name);
- stacktrace->file_name = sr_strdup(newvalue);
- Py_RETURN_NONE;
-}
-
/* methods */
PyObject *
sr_py_python_stacktrace_dup(PyObject *self, PyObject *args)
diff --git a/python/py_python_stacktrace.h b/python/py_python_stacktrace.h
index a5128b7..e8e1d31 100644
--- a/python/py_python_stacktrace.h
+++ b/python/py_python_stacktrace.h
@@ -52,15 +52,6 @@ void sr_py_python_stacktrace_free(PyObject *object);
/* str */
PyObject *sr_py_python_stacktrace_str(PyObject *self);
-/* getters & setters */
-PyObject *sr_py_python_stacktrace_get_file_name(PyObject *self, PyObject *args);
-PyObject *sr_py_python_stacktrace_set_file_name(PyObject *self, PyObject *args);
-PyObject *sr_py_python_stacktrace_get_file_line(PyObject *self, PyObject *args);
-PyObject *sr_py_python_stacktrace_set_file_line(PyObject *self, PyObject *args);
-PyObject *sr_py_python_stacktrace_get_exception_name(PyObject *self, PyObject *args);
-PyObject *sr_py_python_stacktrace_set_exception_name(PyObject *self, PyObject *args);
-
-
/* methods */
PyObject *sr_py_python_stacktrace_dup(PyObject *self, PyObject *args);
PyObject *sr_py_python_stacktrace_normalize(PyObject *self, PyObject *args);
diff --git a/tests/python/gdb.py b/tests/python/gdb.py
index 3a6b66f..54f0fbf 100755
--- a/tests/python/gdb.py
+++ b/tests/python/gdb.py
@@ -2,6 +2,7 @@
import os
import unittest
+from test_helpers import BindingsTestCase
try:
import _satyr as satyr
@@ -19,7 +20,7 @@ if not os.path.isfile(path):
with file(path) as f:
contents = f.read()
-class TestGdbStacktrace(unittest.TestCase):
+class TestGdbStacktrace(BindingsTestCase):
def setUp(self):
self.trace = satyr.GdbStacktrace(contents)
@@ -55,15 +56,24 @@ class TestGdbStacktrace(unittest.TestCase):
out = str(self.trace)
self.assertTrue(('Stacktrace with %d threads' % threads_expected) in
out)
-class TestGdbThread(unittest.TestCase):
+class TestGdbThread(BindingsTestCase):
def setUp(self):
self.thread = satyr.GdbStacktrace(contents).threads[0]
-class TestGdbSharedlib(unittest.TestCase):
+ def test_getset(self):
+ self.assertGetSetCorrect(self.thread, 'number', 2, 9000)
+
+class TestGdbSharedlib(BindingsTestCase):
def setUp(self):
self.shlib = satyr.GdbStacktrace(contents).libs[0]
-class TestGdbFrame(unittest.TestCase):
+ def test_getset(self):
+ self.assertGetSetCorrect(self.shlib, 'start_address', 0x3ecd63c680, 10)
+ self.assertGetSetCorrect(self.shlib, 'end_address', 0x3ecd71f0f8, 20)
+ self.assertGetSetCorrect(self.shlib, 'symbols', satyr.SYMS_OK,
satyr.SYMS_WRONG)
+ self.assertGetSetCorrect(self.shlib, 'soname',
'/usr/lib64/libpython2.6.so.1.0', '/dev/null')
+
+class TestGdbFrame(BindingsTestCase):
def setUp(self):
self.frame = satyr.GdbStacktrace(contents).threads[0].frames[0]
@@ -75,20 +85,33 @@ class TestGdbFrame(unittest.TestCase):
def test_dup(self):
dup = self.frame.dup()
- self.assertEqual(dup.get_function_name(),
- self.frame.get_function_name())
+ self.assertEqual(dup.function_name,
+ self.frame.function_name)
- dup.set_function_name('other')
- self.assertNotEqual(dup.get_function_name(),
- self.frame.get_function_name())
+ dup.function_name = 'other'
+ self.assertNotEqual(dup.function_name,
+ self.frame.function_name)
def test_cmp(self):
dup = self.frame.dup()
self.assertEqual(dup.cmp(dup, 0), 0)
self.assertEqual(dup.cmp(self.frame, 0), 0)
self.assertEqual(dup.cmp(self.frame, 0), 0)
- dup.set_function_name('another')
+ dup.function_name = 'another'
self.assertNotEqual(dup.cmp(self.frame, 0), 0)
+ def test_getset(self):
+ self.assertGetSetCorrect(self.frame, 'function_name', 'write',
'foo bar')
+ self.assertGetSetCorrect(self.frame, 'function_type', None, 'Maybe
Integer')
+ self.assertGetSetCorrect(self.frame, 'number', 0, 42)
+ self.assertGetSetCorrect(self.frame, 'source_file',
'../sysdeps/unix/syscall-template.S', 'ok.c')
+ self.assertGetSetCorrect(self.frame, 'source_line', 82, 1337)
+ self.assertGetSetCorrect(self.frame, 'signal_handler_called', False,
True)
+ self.assertGetSetCorrect(self.frame, 'address', 0x3ec220e48d, 0x666)
+ self.assertGetSetCorrect(self.frame, 'address', 0x666, 4398046511104L)
+ ## 2^66, this is expected to fail
+ #self.assertGetSetCorrect(self.frame, 'address', 4398046511104L,
73786976294838206464L)
+ self.assertGetSetCorrect(self.frame, 'library_name', None,
'sowhat.so')
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/python/java.py b/tests/python/java.py
index 81a93c1..3e331b4 100755
--- a/tests/python/java.py
+++ b/tests/python/java.py
@@ -2,6 +2,7 @@
import os
import unittest
+from test_helpers import BindingsTestCase
try:
import _satyr as satyr
@@ -18,7 +19,7 @@ if not os.path.isfile(path):
with file(path) as f:
contents = f.read()
-class TestJavaStacktrace(unittest.TestCase):
+class TestJavaStacktrace(BindingsTestCase):
def setUp(self):
self.trace = satyr.JavaStacktrace(contents)
@@ -49,15 +50,18 @@ class TestJavaStacktrace(unittest.TestCase):
out = str(self.trace)
self.assertTrue(('Java stacktrace with %d threads' % threads_expected) in
out)
-class TestJavaThread(unittest.TestCase):
+class TestJavaThread(BindingsTestCase):
def setUp(self):
self.thread = satyr.JavaStacktrace(contents).threads[0]
-class TestJavaSharedlib(unittest.TestCase):
+ def test_getset(self):
+ self.assertGetSetCorrect(self.thread, 'name', None, 'elvis')
+
+class TestJavaSharedlib(BindingsTestCase):
def setUp(self):
self.shlib = satyr.JavaStacktrace(contents).libs[0]
-class TestJavaFrame(unittest.TestCase):
+class TestJavaFrame(BindingsTestCase):
def setUp(self):
self.frame = satyr.JavaStacktrace(contents).threads[0].frames[0]
@@ -69,20 +73,32 @@ class TestJavaFrame(unittest.TestCase):
def test_dup(self):
dup = self.frame.dup()
- self.assertEqual(dup.get_name(),
- self.frame.get_name())
+ self.assertEqual(dup.name,
+ self.frame.name)
- dup.set_name('other')
- self.assertNotEqual(dup.get_name(),
- self.frame.get_name())
+ dup.name = 'other'
+ self.assertNotEqual(dup.name,
+ self.frame.name)
def test_cmp(self):
dup = self.frame.dup()
self.assertEqual(dup.cmp(dup), 0)
self.assertEqual(dup.cmp(self.frame), 0)
self.assertEqual(dup.cmp(self.frame), 0)
- dup.set_name('another')
+ dup.name = 'another'
self.assertNotEqual(dup.cmp(self.frame), 0)
+ def test_getset(self):
+ self.assertGetSetCorrect(self.frame, 'name',
'org.hibernate.exception.ConstraintViolationException',
'long.name.is.Long')
+ self.assertGetSetCorrect(self.frame, 'file_name', None,
'java.java')
+ self.assertGetSetCorrect(self.frame, 'file_line', 0, 1234)
+ self.assertGetSetCorrect(self.frame, 'class_path', None,
'/path/to/class')
+ self.assertGetSetCorrect(self.frame, 'is_exception', True, False)
+ ## not bool, expected to fail
+ #self.assertGetSetCorrect(self.frame, 'is_exception', False, 1)
+ self.assertGetSetCorrect(self.frame, 'is_native', False, True)
+ self.assertGetSetCorrect(self.frame, 'message', 'could not insert:
[com.example.myproject.MyEntity]', 'printer on fire')
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/python/koops.py b/tests/python/koops.py
index 34292d4..fbeb8dd 100755
--- a/tests/python/koops.py
+++ b/tests/python/koops.py
@@ -2,6 +2,7 @@
import os
import unittest
+from test_helpers import BindingsTestCase
try:
import _satyr as satyr
@@ -18,7 +19,7 @@ if not os.path.isfile(path):
with file(path) as f:
contents = f.read()
-class TestKerneloops(unittest.TestCase):
+class TestKerneloops(BindingsTestCase):
def setUp(self):
self.koops = satyr.Kerneloops(contents)
@@ -26,7 +27,10 @@ class TestKerneloops(unittest.TestCase):
self.assertEqual(len(self.koops.frames), frames_expected)
def test_correct_modules(self):
- self.assertEqual(len(self.koops.get_modules()), mods_expected)
+ self.assertEqual(len(self.koops.modules), mods_expected)
+ ## not implemented, expected to fail
+ #self.koops.modules = ['foo', 'bar']
+ #self.assertEqual(len(self.koops.modules), 2)
def test_dup(self):
dup = self.koops.dup()
@@ -46,7 +50,7 @@ class TestKerneloops(unittest.TestCase):
out = str(self.koops)
self.assertTrue(('Kerneloops with %d frames' % frames_expected) in out)
-class TestKoopsFrame(unittest.TestCase):
+class TestKoopsFrame(BindingsTestCase):
def setUp(self):
self.frame = satyr.Kerneloops(contents).frames[0]
@@ -59,20 +63,33 @@ class TestKoopsFrame(unittest.TestCase):
def test_dup(self):
dup = self.frame.dup()
- self.assertEqual(dup.get_function_name(),
- self.frame.get_function_name())
+ self.assertEqual(dup.function_name,
+ self.frame.function_name)
- dup.set_function_name('other')
- self.assertNotEqual(dup.get_function_name(),
- self.frame.get_function_name())
+ dup.function_name = 'other'
+ self.assertNotEqual(dup.function_name,
+ self.frame.function_name)
def test_cmp(self):
dup = self.frame.dup()
self.assertEqual(dup.cmp(dup), 0)
self.assertEqual(dup.cmp(self.frame), 0)
self.assertEqual(dup.cmp(self.frame), 0)
- dup.set_reliable(False)
+ dup.reliable = False
self.assertNotEqual(dup.cmp(self.frame), 0)
+ def test_getset(self):
+ self.assertGetSetCorrect(self.frame, 'reliable', True, False)
+ self.assertGetSetCorrect(self.frame, 'address', 0xffffffff81057adfL,
60200)
+ self.assertGetSetCorrect(self.frame, 'function_name',
'warn_slowpath_common', 'fun_ction')
+ self.assertGetSetCorrect(self.frame, 'function_offset', 0x7f, 890)
+ self.assertGetSetCorrect(self.frame, 'function_length', 0xc0, 234)
+ self.assertGetSetCorrect(self.frame, 'module_name', None,
'dev_one.ko')
+ self.assertGetSetCorrect(self.frame, 'from_address', 0, 333333)
+ self.assertGetSetCorrect(self.frame, 'from_function_name', None,
'teh_caller')
+ self.assertGetSetCorrect(self.frame, 'from_function_offset', 0, 0x31337)
+ self.assertGetSetCorrect(self.frame, 'from_function_length', 0, 1024)
+ self.assertGetSetCorrect(self.frame, 'from_module_name', None,
'asdf')
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/python/python.py b/tests/python/python.py
index 5ef2975..59d61ce 100755
--- a/tests/python/python.py
+++ b/tests/python/python.py
@@ -3,6 +3,8 @@
import os
import unittest
+from test_helpers import BindingsTestCase
+
try:
import _satyr as satyr
except ImportError:
@@ -17,7 +19,7 @@ if not os.path.isfile(path):
with file(path) as f:
contents = f.read()
-class TestPythonStacktrace(unittest.TestCase):
+class TestPythonStacktrace(BindingsTestCase):
def setUp(self):
self.trace = satyr.PythonStacktrace(contents)
@@ -45,7 +47,12 @@ class TestPythonStacktrace(unittest.TestCase):
out = str(self.trace)
self.assertTrue(('Python stacktrace with %d frames' % frames_expected) in
out)
-class TestPythonFrame(unittest.TestCase):
+ def test_getset(self):
+ self.assertGetSetCorrect(self.trace, 'file_name', None,
'moo.py')
+ self.assertGetSetCorrect(self.trace, 'file_line', 0, 42)
+ self.assertGetSetCorrect(self.trace, 'exception_name',
'AttributeError', 'WhateverException')
+
+class TestPythonFrame(BindingsTestCase):
def setUp(self):
self.frame = satyr.PythonStacktrace(contents).frames[0]
@@ -57,20 +64,27 @@ class TestPythonFrame(unittest.TestCase):
def test_dup(self):
dup = self.frame.dup()
- self.assertEqual(dup.get_function_name(),
- self.frame.get_function_name())
+ self.assertEqual(dup.function_name,
+ self.frame.function_name)
- dup.set_function_name('other')
- self.assertNotEqual(dup.get_function_name(),
- self.frame.get_function_name())
+ dup.function_name = 'other'
+ self.assertNotEqual(dup.function_name,
+ self.frame.function_name)
def test_cmp(self):
dup = self.frame.dup()
self.assertEqual(dup.cmp(dup), 0)
self.assertEqual(dup.cmp(self.frame), 0)
self.assertEqual(dup.cmp(self.frame), 0)
- dup.set_function_name('another')
+ dup.function_name = 'another'
self.assertNotEqual(dup.cmp(self.frame), 0)
+ def test_getset(self):
+ self.assertGetSetCorrect(self.frame, 'file_name',
'/usr/share/PackageKit/helpers/yum/yumBackend.py', 'java.py')
+ self.assertGetSetCorrect(self.frame, 'file_line', 1830, 6667)
+ self.assertGetSetCorrect(self.frame, 'is_module', False, True)
+ self.assertGetSetCorrect(self.frame, 'function_name',
'_runYumTransaction', 'iiiiii')
+ self.assertGetSetCorrect(self.frame, 'line_contents',
'rpmDisplay=rpmDisplay)', 'abcde')
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/python/test_helpers.py b/tests/python/test_helpers.py
new file mode 100644
index 0000000..4bd03a0
--- /dev/null
+++ b/tests/python/test_helpers.py
@@ -0,0 +1,14 @@
+import unittest
+
+class BindingsTestCase(unittest.TestCase):
+ def assertGetSetCorrect(self, obj, attr, orig_val, new_val):
+ '''
+ Check whether getting/setting an attribute works correctly.
+ '''
+ self.assertEqual(obj.__getattribute__(attr), orig_val)
+ obj.__setattr__(attr, new_val)
+ self.assertEqual(obj.__getattribute__(attr), new_val)
+
+if __name__ == '__main__':
+ import sys
+ sys.exit('This module is not meant to be run directly')
--
1.7.11.7