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 | 127 +++++++++++++++
python/py_common.h | 126 +++++++++++++++
python/py_gdb_frame.c | 311 ++++++++----------------------------
python/py_gdb_frame.h | 18 ---
python/py_gdb_sharedlib.c | 152 ++++--------------
python/py_gdb_sharedlib.h | 13 +-
python/py_gdb_thread.c | 57 +++----
python/py_gdb_thread.h | 4 -
python/py_java_frame.c | 242 ++++------------------------
python/py_java_frame.h | 16 --
python/py_java_thread.c | 50 ++----
python/py_java_thread.h | 4 -
python/py_koops_frame.c | 356 +++++-------------------------------------
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 | 180 ++++-----------------
python/py_python_frame.h | 12 --
python/py_python_stacktrace.c | 118 +++-----------
python/py_python_stacktrace.h | 9 --
tests/python/gdb.py | 43 +++--
tests/python/java.py | 35 +++--
tests/python/koops.py | 35 +++--
tests/python/python.py | 30 +++-
tests/python/test_helpers.py | 14 ++
27 files changed, 658 insertions(+), 1353 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..15aa108
--- /dev/null
+++ b/python/py_common.c
@@ -0,0 +1,127 @@
+/*
+ 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;
+
+ bool newvalue = PyObject_IsTrue(rhs);
+ 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..7b9dc82
--- /dev/null
+++ b/python/py_common.h
@@ -0,0 +1,126 @@
+/*
+ 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, st, 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 ;
+
+/*
+ * Once you declare GSOFF_MEMBER() macro for each member you want to expose in
+ * python, you can use following macros to define PyGetSetDef structures.
+ *
+ * The _R variants stand for "rename" in case you want the python attribute to
+ * have different than the corresponding C member.
+ *
+ * See python/py_gdb_sharedlib.c for sample usage of both.
+ */
+#define SR_ATTRIBUTE_STRING_R(name, c_member, doc_str) \
+ { (char*)name, sr_py_getter_string, sr_py_setter_string, (char*)doc_str,
&gsoff_ ## c_member }
+#define SR_ATTRIBUTE_STRING(c_member, doc_str) SR_ATTRIBUTE_STRING_R(#c_member, c_member,
doc_str)
+
+#define SR_ATTRIBUTE_UINT32_R(name, c_member, doc_str) \
+ { (char*)name, sr_py_getter_uint32, sr_py_setter_uint32, (char*)doc_str,
&gsoff_ ## c_member }
+#define SR_ATTRIBUTE_UINT32(c_member, doc_str) SR_ATTRIBUTE_UINT32_R(#c_member, c_member,
doc_str)
+
+#define SR_ATTRIBUTE_UINT64_R(name, c_member, doc_str) \
+ { (char*)name, sr_py_getter_uint64, sr_py_setter_uint64, (char*)doc_str,
&gsoff_ ## c_member }
+#define SR_ATTRIBUTE_UINT64(c_member, doc_str) SR_ATTRIBUTE_UINT64_R(#c_member, c_member,
doc_str)
+
+#define SR_ATTRIBUTE_BOOL_R(name, c_member, doc_str) \
+ { (char*)name, sr_py_getter_bool, sr_py_setter_bool, (char*)doc_str, &gsoff_
## c_member }
+#define SR_ATTRIBUTE_BOOL(c_member, doc_str) SR_ATTRIBUTE_BOOL_R(#c_member, c_member,
doc_str)
+
+/*
+ * 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..6bfd700 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,54 +32,6 @@
"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_dup_doc "Usage: frame.dup()\n" \
"Returns: satyr.GdbFrame - a new clone of frame\n" \
"Clones the frame object. All new structures are independent
" \
@@ -109,28 +62,72 @@
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
the 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 the 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
+
+/*
+ * With the GSOFF_ declarations above, we can use SR_ATTRIBUTE_ macros that
+ * expand to PyGetSetDef literals with the right values. There is also
+ * SR_ATTRIBUTE_type_R variant that allows you to name the attribute different
+ * than the C struct member.
+ */
+static PyGetSetDef
+frame_getset[] =
+{
+ SR_ATTRIBUTE_STRING(function_name, "Function name (string)"
),
+ SR_ATTRIBUTE_STRING(function_type, "Function type (string)"
),
+ SR_ATTRIBUTE_UINT32(number, "Frame number (positive
integer)" ),
+ SR_ATTRIBUTE_STRING(source_file, "Source file name (string)"
),
+ SR_ATTRIBUTE_UINT32(source_line, "Source line number (positive
integer)" ),
+ SR_ATTRIBUTE_BOOL (signal_handler_called, "True if the frame is signal handler
(bool)"),
+ SR_ATTRIBUTE_UINT64(address, "Address of the current instruction
(long)" ),
+ SR_ATTRIBUTE_STRING(library_name, "Executable file name (string)"
),
{ NULL },
};
@@ -165,9 +162,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 +246,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..4d34278 100644
--- a/python/py_gdb_sharedlib.c
+++ b/python/py_gdb_sharedlib.c
@@ -1,61 +1,32 @@
+#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_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."
+
+/* 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 },
+ SR_ATTRIBUTE_UINT64_R("start_address", from, "Address where lib's
memory begins (long)"),
+ SR_ATTRIBUTE_UINT64_R("end_address", to, "Address where lib's
memory ends (long)" ),
+ SR_ATTRIBUTE_STRING(soname, "Library file name (string)"),
+ { (char*)"symbols", sr_py_gdb_sharedlib_get_symbols,
sr_py_gdb_sharedlib_set_symbols, (char*)s_symbols_doc, NULL },
{ NULL },
};
@@ -90,9 +61,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 +93,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 +115,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..507f978 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,48 +29,6 @@
"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_dup_doc "Usage: frame.dup()\n" \
"Returns: satyr.JavaFrame - a new clone of frame\n" \
"Clones the frame object. All new structures are independent
" \
@@ -86,27 +45,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[] =
+{
+ SR_ATTRIBUTE_STRING(name, "Fully qualified domain name (string)"
),
+ SR_ATTRIBUTE_STRING(file_name, "File name (string)"
),
+ SR_ATTRIBUTE_UINT32(file_line, "File line (positive integer)"
),
+ SR_ATTRIBUTE_STRING(class_path, "Class path (string)"
),
+ SR_ATTRIBUTE_BOOL (is_native, "True if method is native, always false if
frame is an exception (bool)"),
+ SR_ATTRIBUTE_BOOL (is_exception, "True if frame is an exception frame
(bool)" ),
+ SR_ATTRIBUTE_STRING(message, "Exception message (string)"
),
+ { NULL }
+};
+
PyTypeObject
sr_py_java_frame_type =
{
@@ -140,7 +111,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 +213,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..d70af6e 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,12 +13,6 @@
"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_dup_doc "Usage: thread.dup()\n" \
"Returns: satyr.JavaThread - a new clone of thread\n" \
"Clones the thread object. All new structures are independent
" \
@@ -49,9 +44,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 +60,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[] =
+{
+ SR_ATTRIBUTE_STRING(name, "Thread name (string)"),
+ { NULL },
+};
+
PyTypeObject sr_py_java_thread_type =
{
PyObject_HEAD_INIT(NULL)
@@ -100,7 +107,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 +278,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..778af3f 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,75 +32,6 @@
"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_dup_doc "Usage: frame.dup()\n" \
"Returns: satyr.KerneloopsFrame - a new clone of frame\n" \
"Clones the frame object. All new structures are independent
" \
@@ -116,36 +48,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[] =
+{
+ SR_ATTRIBUTE_BOOL (reliable, "True if the the frame is guaranteed
to be real (bool)"),
+ SR_ATTRIBUTE_UINT64(address, "Address of the current instruction
(long)" ),
+ SR_ATTRIBUTE_STRING(function_name, "Function name (string)"
),
+ SR_ATTRIBUTE_UINT64(function_offset, "Function offset (long)"
),
+ SR_ATTRIBUTE_UINT64(function_length, "Function length (long)"
),
+ SR_ATTRIBUTE_STRING(module_name, "Module owning the function
(string)" ),
+ SR_ATTRIBUTE_UINT64(from_address, "Address of the caller's
instruction (long)" ),
+ SR_ATTRIBUTE_STRING(from_function_name, "Caller function name (string)"
),
+ SR_ATTRIBUTE_UINT64(from_function_offset, "Caller function offset (long)"
),
+ SR_ATTRIBUTE_UINT64(from_function_length, "Caller function length (long)"
),
+ SR_ATTRIBUTE_STRING(from_module_name, "Module owning the caller function
(string)" ),
+ { NULL },
+};
+
PyTypeObject
sr_py_koops_frame_type =
{
@@ -179,7 +122,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 +221,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..9e5e5c6 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,36 +29,6 @@
"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_dup_doc "Usage: frame.dup()\n" \
"Returns: satyr.PythonFrame - a new clone of frame\n" \
"Clones the frame object. All new structures are independent
" \
@@ -74,20 +45,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[] =
+{
+ SR_ATTRIBUTE_STRING(file_name, "Source file name (string)"
),
+ SR_ATTRIBUTE_UINT32(file_line, "Source line number (positive integer)"
),
+ SR_ATTRIBUTE_BOOL (is_module, "True if the frame is from the main module
(bool)"),
+ SR_ATTRIBUTE_STRING(function_name, "Function name (string)"
),
+ SR_ATTRIBUTE_STRING(line_contents, "Remaining line contents (string)"
),
{ NULL },
};
@@ -124,7 +107,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 +195,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..e2c712f 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,24 +13,6 @@
"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_dup_doc "Usage: stacktrace.dup()\n" \
"Returns: satyr.PythonStacktrace - a new clone of python
stacktrace\n" \
"Clones the PythonStacktrace object. All new structures are
independent " \
@@ -46,16 +29,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 +42,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[] =
+{
+ SR_ATTRIBUTE_STRING(file_name, "Source file name (string)"
),
+ SR_ATTRIBUTE_UINT32(file_line, "Source line number (positive
integer)"),
+ SR_ATTRIBUTE_STRING(exception_name, "Exception type (string)"
),
+ { NULL },
+};
+
PyTypeObject sr_py_python_stacktrace_type = {
PyObject_HEAD_INIT(NULL)
0,
@@ -97,7 +92,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 +263,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..37bf286 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,31 @@ 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)
+ 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