From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18421 invoked by alias); 28 Feb 2009 19:26:46 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 18348 invoked by uid 9674); 28 Feb 2009 19:26:42 -0000 Date: Sat, 28 Feb 2009 19:26:00 -0000 Message-ID: <20090228192641.18333.qmail@sourceware.org> From: jkratoch@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer: Merge commit 'origin/archer-jankratochvil-python' into archer X-Git-Refname: refs/heads/archer X-Git-Reftype: branch X-Git-Oldrev: fe2f5da6755411c681cb4c5adb6d8b9b91e316a3 X-Git-Newrev: 4070e63dc60ffe868c9b90f3c97ee57cd7ec0287 X-SW-Source: 2009-q1/txt/msg00214.txt.bz2 List-Id: The branch, archer has been updated via 4070e63dc60ffe868c9b90f3c97ee57cd7ec0287 (commit) via 8cfb53175964b36c34f54147a3ea057c9a7fd728 (commit) via 9f2e8a3ed0db5ebf8e1e25e691b9826010e5c005 (commit) via 3d2d45e9b846b6754a8215a85e3ac72c3c0b73bf (commit) via ebadcf6e954061122d1c6d0a1e79de5cf23b85b8 (commit) via 0686961df93c7c2d16b6ae25d78de382037a2f8c (commit) via acd14fd258b498d2faa5dc34751c43da5c8e476f (commit) via 960557011f37ee49ac8109c9090e1f8ac5df41a9 (commit) via 73864473aa5f3f47d681c6a1d95e04c2ecff2180 (commit) via 745c2e91d30f0ee78c2a9e2779b807f382be51d1 (commit) via 8d7cda5302bef3e53337906e3ac3f5dffaa372ca (commit) via 2206b86f85f03bf20dbe642703bc02ad58a35e61 (commit) via 6dd3e965ad875563547f5d36ae74e3940050c706 (commit) via d19d9fde47e23944526327e3c7942b93c4ac4277 (commit) from fe2f5da6755411c681cb4c5adb6d8b9b91e316a3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 4070e63dc60ffe868c9b90f3c97ee57cd7ec0287 Merge: 9f2e8a3ed0db5ebf8e1e25e691b9826010e5c005 8cfb53175964b36c34f54147a3ea057c9a7fd728 Author: Jan Kratochvil Date: Sat Feb 28 20:25:59 2009 +0100 Merge commit 'origin/archer-jankratochvil-python' into archer commit 9f2e8a3ed0db5ebf8e1e25e691b9826010e5c005 Merge: 3d2d45e9b846b6754a8215a85e3ac72c3c0b73bf 0686961df93c7c2d16b6ae25d78de382037a2f8c Author: Jan Kratochvil Date: Sat Feb 28 20:18:53 2009 +0100 Merge commit 'origin/archer-jankratochvil-vla' into archer commit 3d2d45e9b846b6754a8215a85e3ac72c3c0b73bf Merge: fe2f5da6755411c681cb4c5adb6d8b9b91e316a3 ebadcf6e954061122d1c6d0a1e79de5cf23b85b8 Author: Jan Kratochvil Date: Sat Feb 28 20:18:40 2009 +0100 Merge commit 'origin/archer-jankratochvil-python' into archer ----------------------------------------------------------------------- Summary of changes: gdb/doc/gdb.texinfo | 16 +++- gdb/gdbtypes.c | 34 +++----- gdb/python/python-cmd.c | 12 ++- gdb/python/python-frame.c | 136 +++++++++++++++++++++++++------ gdb/python/python-internal.h | 2 +- gdb/python/python-symbol.c | 18 +++-- gdb/python/python-value.c | 16 +++-- gdb/python/python.c | 37 +++++--- gdb/testsuite/gdb.python/find.exp | 43 +++++++--- gdb/testsuite/gdb.python/python-cmd.exp | 26 ++++++ 10 files changed, 241 insertions(+), 99 deletions(-) First 500 lines of diff: diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index d0e68d5..c506fb7 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -18244,6 +18244,14 @@ auto-loading is disabled. @cindex python api @cindex programming in python +You can get quick online help for @value{GDBN}'s Python API by issuing +the command @w{@kbd{python help (gdb)}}. + +Functions and methods which have two or more optional arguments allow +them to be specified using keyword syntax. This allows passing some +optional arguments while skipping others. Example: +@w{@code{gdb.some_function ('foo', bar = 1, baz = 2)}}. + @cindex python stdout @cindex python pagination At startup, @value{GDBN} overrides Python's @code{sys.stdout} and @@ -18563,7 +18571,7 @@ The result @code{bar} will be a @code{gdb.Value} object holding the value pointed to by @code{foo}. @end defmethod -@defmethod Value string @r{[}encoding @r{[}errors@r{]}@r{]} +@defmethod Value string @r{[}encoding@r{]} @r{[}errors@r{]} If this @code{gdb.Value} represents a string, then this method converts the contents to a Python string. Otherwise, this method will throw an exception. @@ -19063,7 +19071,7 @@ You can implement new @value{GDBN} CLI commands in Python. A CLI command is implemented using an instance of the @code{gdb.Command} class, most commonly using a subclass. -@defmethod Command __init__ name @var{command-class} @r{[}@var{completer-class} @var{prefix}@r{]} +@defmethod Command __init__ name @var{command_class} @r{[}@var{completer_class}@r{]} @r{[}@var{prefix}@r{]} The object initializer for @code{Command} registers the new command with @value{GDBN}. This initializer is normally invoked from the subclass' own @code{__init__} method. @@ -19075,11 +19083,11 @@ an exception is raised. There is no support for multi-line commands. -@var{command-class} should be one of the @samp{COMMAND_} constants +@var{command_class} should be one of the @samp{COMMAND_} constants defined below. This argument tells @value{GDBN} how to categorize the new command in the help system. -@var{completer-class} is an optional argument. If given, it should be +@var{completer_class} is an optional argument. If given, it should be one of the @samp{COMPLETE_} constants defined below. This argument tells @value{GDBN} how to perform completion for this command. If not given, @value{GDBN} will attempt to complete using the object's diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index e6190cf..b3217fb 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -3504,16 +3504,14 @@ type_incref (struct type *type) } /* A traverse callback for type_refc_table which removes any entry - whose reference count pointer is REFC. REFC may be NULL to delete all the - unused entries - use such cleanup only in the GDB idle state as GDB code - does not necessarily reference county TYPEs during its processing. */ + whose reference count is zero (unused entry). */ static int -type_refc_remove (void **slot, void *refc) +type_refc_remove (void **slot, void *unused) { struct type_refc_entry *entry = *slot; - if (entry->refc == refc || (refc == NULL && *entry->refc == 0)) + if (*entry->refc == 0) { delete_type (entry->type); @@ -3524,8 +3522,10 @@ type_refc_remove (void **slot, void *refc) return 1; } -/* Decrement the reference count for TYPE. If TYPE has no more - references, delete it. */ +/* Decrement the reference count for TYPE. Even if TYPE has no more + references still do not delete it as callers may hold pointers to types + dynamically generated by check_typedef where type_incref is never called. + Always rely on the free_all_types garbage collector. */ void type_decref (struct type *type) @@ -3538,24 +3538,14 @@ type_decref (struct type *type) entry.type = type; found = htab_find (type_refc_table, &entry); gdb_assert (found); + gdb_assert (found->refc > 0); --*(found->refc); - if (*(found->refc) == 0) - { - void *refc = found->refc; - - /* Clear all table entries referring to this count. CHECK: Should not be - the deletion delayed till free_all_types? */ - delete_type_begin (); - htab_traverse (type_refc_table, type_refc_remove, refc); - delete_type_finish (); - - /* Delete the reference count itself. */ - xfree (refc); - } } -/* Free all the types that have been allocated (except for those released). - Called after each command, successful or not. */ +/* Free all the types that have been allocated and that are not used according + to type_refc_entry->refc. Called after each command, successful or not. + Use this cleanup only in the GDB idle state as GDB code does not necessarily + use type_incref / type_decref during temporary use of types. */ void free_all_types (void) diff --git a/gdb/python/python-cmd.c b/gdb/python/python-cmd.c index 90cc780..e6e3ac0 100644 --- a/gdb/python/python-cmd.c +++ b/gdb/python/python-cmd.c @@ -337,16 +337,16 @@ gdbpy_parse_command_name (char *text, struct cmd_list_element ***base_list, /* Object initializer; sets up gdb-side structures for command. - Use: __init__(NAME, CMDCLASS, [COMPLETERCLASS, [PREFIX]]). + Use: __init__(NAME, COMMAND_CLASS, [COMPLETER_CLASS, [PREFIX]]). NAME is the name of the command. It may consist of multiple words, in which case the final word is the name of the new command, and earlier words must be prefix commands. - CMDCLASS is the kind of command. It should be one of the COMMAND_* + COMMAND_CLASS is the kind of command. It should be one of the COMMAND_* constants defined in the gdb module. - COMPLETERCLASS is the kind of completer. If not given, the + COMPLETER_CLASS is the kind of completer. If not given, the "complete" method will be used. Otherwise, it should be one of the COMPLETE_* constants defined in the gdb module. @@ -357,7 +357,7 @@ gdbpy_parse_command_name (char *text, struct cmd_list_element ***base_list, */ static int -cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds) +cmdpy_init (PyObject *self, PyObject *args, PyObject *kw) { cmdpy_object *obj = (cmdpy_object *) self; char *name; @@ -367,6 +367,8 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds) volatile struct gdb_exception except; struct cmd_list_element **cmd_list; char *cmd_name, *pfx_name; + static char *keywords[] = { "name", "command_class", "completer_class", + "prefix", NULL }; PyObject *is_prefix = NULL; int cmp; @@ -379,7 +381,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds) return -1; } - if (! PyArg_ParseTuple (args, "si|iO", &name, &cmdtype, + if (! PyArg_ParseTupleAndKeywords (args, kw, "si|iO", keywords, &name, &cmdtype, &completetype, &is_prefix)) return -1; diff --git a/gdb/python/python-frame.c b/gdb/python/python-frame.c index c2224cf..ef1c178 100644 --- a/gdb/python/python-frame.c +++ b/gdb/python/python-frame.c @@ -1,6 +1,6 @@ /* Python interface to stack frames - Copyright (C) 2008 Free Software Foundation, Inc. + Copyright (C) 2008, 2009 Free Software Foundation, Inc. This file is part of GDB. @@ -54,6 +54,9 @@ typedef struct { static PyTypeObject frame_object_type; +/* Returns the frame_info object corresponding to the given Python Frame + object. If the frame doesn't exist anymore (the frame id doesn't + correspond to any frame in the inferior), returns NULL. */ static struct frame_info * frame_object_to_frame_info (frame_object *frame_obj) @@ -70,6 +73,9 @@ frame_object_to_frame_info (frame_object *frame_obj) return frame; } +/* Called by the Python interpreter to obtain string representation + of the object. */ + static PyObject * frapy_str (PyObject *self) { @@ -87,6 +93,10 @@ frapy_str (PyObject *self) return result; } +/* Implementation of gdb.Frame.is_valid (self) -> Boolean. + Returns True if the frame corresponding to the frame_id of this + object still exists in the inferior. */ + static PyObject * frapy_is_valid (PyObject *self, PyObject *args) { @@ -99,6 +109,8 @@ frapy_is_valid (PyObject *self, PyObject *args) Py_RETURN_TRUE; } +/* Implementation of gdb.Frame.equals (self, other) -> Boolean. */ + static PyObject * frapy_equal_p (PyObject *self, PyObject *args) { @@ -122,6 +134,9 @@ frapy_equal_p (PyObject *self, PyObject *args) Py_RETURN_FALSE; } +/* Implementation of gdb.Frame.name (self) -> String. + Returns the name of the function corresponding to this frame. */ + static PyObject * frapy_name (PyObject *self, PyObject *args) { @@ -150,6 +165,9 @@ frapy_name (PyObject *self, PyObject *args) return result; } +/* Implementation of gdb.Frame.type (self) -> Integer. + Returns the frame type, namely one of the gdb.*_FRAME constants. */ + static PyObject * frapy_type (PyObject *self, PyObject *args) { @@ -168,6 +186,9 @@ frapy_type (PyObject *self, PyObject *args) return PyInt_FromLong (type); } +/* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer. + Returns one of the gdb.FRAME_UNWIND_* constants. */ + static PyObject * frapy_unwind_stop_reason (PyObject *self, PyObject *args) { @@ -186,6 +207,9 @@ frapy_unwind_stop_reason (PyObject *self, PyObject *args) return PyInt_FromLong (stop_reason); } +/* Implementation of gdb.Frame.pc (self) -> Long. + Returns the frame's resume address. */ + static PyObject * frapy_pc (PyObject *self, PyObject *args) { @@ -204,6 +228,9 @@ frapy_pc (PyObject *self, PyObject *args) return PyLong_FromUnsignedLongLong (pc); } +/* Implementation of gdb.Frame.block (self) -> gdb.Block. + Returns the frame's code block. */ + static PyObject * frapy_block (PyObject *self, PyObject *args) { @@ -225,6 +252,10 @@ frapy_block (PyObject *self, PyObject *args) Py_RETURN_NONE; } + +/* Implementation of gdb.Frame.addr_in_block (self) -> Long. + Returns an address which falls within the frame's code block. */ + static PyObject * frapy_addr_in_block (PyObject *self, PyObject *args) { @@ -243,6 +274,9 @@ frapy_addr_in_block (PyObject *self, PyObject *args) return PyLong_FromUnsignedLongLong (pc); } +/* Convert a frame_info struct to a Python Frame object. + Sets a Python exception and returns NULL on error. */ + static frame_object * frame_info_to_frame_object (struct frame_info *frame) { @@ -276,6 +310,10 @@ frame_info_to_frame_object (struct frame_info *frame) return frame_obj; } +/* Implementation of gdb.Frame.older (self) -> gdb.Frame. + Returns the frame immediately older (outer) to this frame, or None if + there isn't one. */ + static PyObject * frapy_older (PyObject *self, PyObject *args) { @@ -301,6 +339,10 @@ frapy_older (PyObject *self, PyObject *args) return prev_obj; } +/* Implementation of gdb.Frame.newer (self) -> gdb.Frame. + Returns the frame immediately newer (inner) to this frame, or None if + there isn't one. */ + static PyObject * frapy_newer (PyObject *self, PyObject *args) { @@ -326,6 +368,9 @@ frapy_newer (PyObject *self, PyObject *args) return next_obj; } +/* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line. + Returns the frame's symtab and line. */ + static PyObject * frapy_find_sal (PyObject *self, PyObject *args) { @@ -346,6 +391,11 @@ frapy_find_sal (PyObject *self, PyObject *args) return sal_obj; } +/* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value. + Returns the value of the given variable in this frame. The argument can be + either a gdb.Symbol or a string. Returns None if GDB can't find the + specified variable. */ + static PyObject * frapy_read_var_value (PyObject *self, PyObject *args) { @@ -355,13 +405,33 @@ frapy_read_var_value (PyObject *self, PyObject *args) struct value *val = NULL; volatile struct gdb_exception except; - if (!PyArg_ParseTuple (args, "O!", &symbol_object_type, &sym_obj)) + if (!PyArg_ParseTuple (args, "O", &sym_obj)) return NULL; - var = symbol_object_to_symbol (sym_obj); - if (! var) + if (PyObject_TypeCheck (sym_obj, &symbol_object_type)) + var = symbol_object_to_symbol (sym_obj); + else if (gdbpy_is_string (sym_obj)) { - PyErr_SetString (PyExc_RuntimeError, "second argument must be symbol"); + char *var_name; + struct block *block; + volatile struct gdb_exception except; + + TRY_CATCH (except, RETURN_MASK_ALL) + { + struct block *block; + + FRAPY_REQUIRE_VALID ((frame_object *) self, frame); + + block = block_for_pc (get_frame_address_in_block (frame)); + var = lookup_symbol (python_string_to_target_string (sym_obj), block, + VAR_DOMAIN, NULL); + } + GDB_PY_HANDLE_EXCEPTION (except); + } + else + { + PyErr_SetString (PyExc_TypeError, + _("argument must be a symbol or string")); return NULL; } @@ -379,6 +449,9 @@ frapy_read_var_value (PyObject *self, PyObject *args) Py_RETURN_NONE; } +/* Implementation of gdb.frames () -> (gdb.Frame, ...). + Returns a tuple of all frame objects. */ + PyObject * gdbpy_frames (PyObject *self, PyObject *args) { @@ -429,6 +502,9 @@ gdbpy_frames (PyObject *self, PyObject *args) return tuple; } +/* Implementation of gdb.newest_frame () -> gdb.Frame. + Returns the newest frame object. */ + PyObject * gdbpy_newest_frame (PyObject *self, PyObject *args) { @@ -446,6 +522,9 @@ gdbpy_newest_frame (PyObject *self, PyObject *args) return (PyObject *) frame_obj; } +/* Implementation of gdb.selected_frame () -> gdb.Frame. + Returns the selected frame object. */ + PyObject * gdbpy_selected_frame (PyObject *self, PyObject *args) { @@ -463,6 +542,9 @@ gdbpy_selected_frame (PyObject *self, PyObject *args) return (PyObject *) frame_obj; } +/* Implementation of gdb.stop_reason_string (Integer) -> String. + Return a string explaining the unwind stop reason. */ + PyObject * gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args) { @@ -482,6 +564,8 @@ gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args) return PyUnicode_Decode (str, strlen (str), host_charset (), NULL); } +/* Sets up the Frame API in the gdb module. */ + void gdbpy_initialize_frames (void) { @@ -523,7 +607,7 @@ static PyMethodDef frame_object_methods[] = { "Return the function name of the frame." }, { "type", frapy_type, METH_NOARGS, "Return the type of the frame." }, { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS, - "Return the function name of the frame." }, + "Return the reason why it's not possible to find frames older than this." }, { "pc", frapy_pc, METH_NOARGS, "Return the frame's resume address." }, { "block", frapy_block, METH_NOARGS, "Return the frame's code block." }, { "addr_in_block", frapy_addr_in_block, METH_NOARGS, @@ -541,26 +625,26 @@ static PyMethodDef frame_object_methods[] = { static PyTypeObject frame_object_type = { PyObject_HEAD_INIT (NULL) - 0, /*ob_size*/ - "gdb.Frame", /*tp_name*/ - sizeof (frame_object), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - frapy_str, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /* ob_size */ + "gdb.Frame", /* tp_name */ + sizeof (frame_object), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + frapy_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ "GDB frame object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 12422af..4aae0aa 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -78,7 +78,7 @@ PyObject *gdbpy_breakpoints (PyObject *, PyObject *); PyObject *gdbpy_frames (PyObject *, PyObject *); PyObject *gdbpy_newest_frame (PyObject *, PyObject *); PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *); -PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args); +PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw); PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args); PyObject *gdbpy_block_for_pc (PyObject *self, PyObject *args); PyObject *gdbpy_read_memory (PyObject *self, PyObject *args); diff --git a/gdb/python/python-symbol.c b/gdb/python/python-symbol.c index 223e6d3..c7fda5c 100644 --- a/gdb/python/python-symbol.c +++ b/gdb/python/python-symbol.c @@ -166,21 +166,23 @@ symbol_object_to_symbol (PyObject *obj) return ((symbol_object *) obj)->symbol; } hooks/post-receive -- Repository for Project Archer.