From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18443 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 18396 invoked by uid 9674); 28 Feb 2009 19:26:45 -0000 Date: Sat, 28 Feb 2009 19:26:00 -0000 Message-ID: <20090228192645.18378.qmail@sourceware.org> From: jkratoch@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-jankratochvil-python: Merge commit 'origin/archer-tromey-python' into archer-jankratochvil-python X-Git-Refname: refs/heads/archer-jankratochvil-python X-Git-Reftype: branch X-Git-Oldrev: ebadcf6e954061122d1c6d0a1e79de5cf23b85b8 X-Git-Newrev: 8cfb53175964b36c34f54147a3ea057c9a7fd728 X-SW-Source: 2009-q1/txt/msg00215.txt.bz2 List-Id: The branch, archer-jankratochvil-python has been updated via 8cfb53175964b36c34f54147a3ea057c9a7fd728 (commit) via 960557011f37ee49ac8109c9090e1f8ac5df41a9 (commit) via 73864473aa5f3f47d681c6a1d95e04c2ecff2180 (commit) via 745c2e91d30f0ee78c2a9e2779b807f382be51d1 (commit) via 8d7cda5302bef3e53337906e3ac3f5dffaa372ca (commit) via 2206b86f85f03bf20dbe642703bc02ad58a35e61 (commit) via 6dd3e965ad875563547f5d36ae74e3940050c706 (commit) via d19d9fde47e23944526327e3c7942b93c4ac4277 (commit) from ebadcf6e954061122d1c6d0a1e79de5cf23b85b8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: gdb/doc/gdb.texinfo | 16 +++- 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 ++++++ 9 files changed, 229 insertions(+), 77 deletions(-) First 500 lines of diff: diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 4f27cdf..be22f07 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -18157,6 +18157,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 @@ -18476,7 +18484,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. @@ -18976,7 +18984,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. @@ -18988,11 +18996,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/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; } -/* This function has less arguments than its C counterpart, to simplify the - Python interface: name, block and domain. The other two arguments are always - assumed to be set, and a tuple with 2 elements is always returned. The first - is the symbol object or None, the second is a boolean with the value of - is_a_field_of_this. */ -PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args) +/* Implementation of + gdb.lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this) + A tuple with 2 elements is always returned. The first is the symbol + object or None, the second is a boolean with the value of + is_a_field_of_this (see comment in lookup_symbol_in_language). */ + +PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw) { int domain = VAR_DOMAIN, is_a_field_of_this = 0; const char *name; + static char *keywords[] = { "name", "block", "domain", NULL }; struct symbol *symbol; PyObject *block_obj = NULL, *ret_tuple, *sym_obj, *bool_obj; struct block *block = NULL; - if (! PyArg_ParseTuple (args, "s|O!i", &name, &block_object_type, &block_obj, - &domain)) + if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!i", keywords, &name, + &block_object_type, &block_obj, &domain)) return NULL; if (block_obj) diff --git a/gdb/python/python-value.c b/gdb/python/python-value.c index ca29f46..de54b9d 100644 --- a/gdb/python/python-value.c +++ b/gdb/python/python-value.c @@ -155,10 +155,11 @@ valpy_type (PyObject *self, PyObject *args) return type_to_type_object (value_type (value)); } -/* Return Unicode string with value contents (assumed to be encoded in the - target's charset). */ +/* Implementation of gdb.Value.string ([encoding] [, errors]) -> string + Return Unicode string with value contents. If ENCODING is not given, + the string is assumed to be encoded in the target's charset. */ static PyObject * -valpy_string (PyObject *self, PyObject *args) +valpy_string (PyObject *self, PyObject *args, PyObject *kw) { int length, ret = 0; gdb_byte *buffer; @@ -169,8 +170,10 @@ valpy_string (PyObject *self, PyObject *args) const char *errors = NULL; const char *user_encoding = NULL; const char *la_encoding = NULL; + static char *keywords[] = { "encoding", "errors" }; - if (!PyArg_ParseTuple (args, "|ss", &user_encoding, &errors)) + if (!PyArg_ParseTupleAndKeywords (args, kw, "|ss", keywords, + &user_encoding, &errors)) return NULL; TRY_CATCH (except, RETURN_MASK_ALL) @@ -915,8 +918,9 @@ static PyMethodDef value_object_methods[] = { { "cast", valpy_cast, METH_VARARGS, "Cast the value to the supplied type." }, { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." }, { "type", valpy_type, METH_NOARGS, "Return type of the value." }, - { "string", valpy_string, METH_VARARGS, - "Return Unicode string representation of the value." }, + { "string", (PyCFunction) valpy_string, METH_VARARGS | METH_KEYWORDS, + "string ([encoding] [, errors]) -> string\n\ hooks/post-receive -- Repository for Project Archer.