From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13313 invoked by alias); 6 Apr 2009 19:25:00 -0000 Received: (qmail 13273 invoked by uid 22791); 6 Apr 2009 19:24:52 -0000 X-SWARE-Spam-Status: No, hits=-0.8 required=5.0 tests=AWL,BAYES_20,J_CHICKENPOX_38,J_CHICKENPOX_84,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx2.redhat.com (HELO mx2.redhat.com) (66.187.237.31) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 06 Apr 2009 19:24:45 +0000 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n36JOcSI029265; Mon, 6 Apr 2009 15:24:38 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n36JOccE028976; Mon, 6 Apr 2009 15:24:39 -0400 Received: from opsy.redhat.com (vpn-12-50.rdu.redhat.com [10.11.12.50]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n36JOa65026094; Mon, 6 Apr 2009 15:24:37 -0400 Received: by opsy.redhat.com (Postfix, from userid 500) id 9F2BA37817A; Mon, 6 Apr 2009 13:24:34 -0600 (MDT) To: Eli Zaretskii Cc: bauerman@br.ibm.com, gdb-patches@sourceware.org Subject: Re: Python pretty-printing [2/6] References: <1238711355.3236.51.camel@localhost.localdomain> From: Tom Tromey Reply-To: Tom Tromey Date: Mon, 06 Apr 2009 19:25:00 -0000 In-Reply-To: (Eli Zaretskii's message of "Fri\, 03 Apr 2009 18\:04\:19 +0300") Message-ID: User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-04/txt/msg00107.txt.bz2 >>>>> "Eli" == Eli Zaretskii writes: I didn't answer most of your questions, I just made the implied changes. Most of the questions read as rhetorical to me. If they weren't, and you really wanted answers, let me know and I will reply again. >> +@defivar Objfile pretty_printers >> +The @code{pretty_printers} attribute is used to look up >> +pretty-printers by type. This is a dictionary which maps regular >> +expressions (strings) to pretty-printing objects. Eli> I think we want a cross-reference here to where pretty-printing is Eli> described. This comes in a later patch. Here's the updated patch. I've tried to address all the comments that anybody raised. Also, I fixed the documentation for Objfile.pretty_printers to reflect reality. Tom 2009-04-01 Tom Tromey Thiago Jung Bauermann Phil Muldoon * python/python.c: Include objfiles.h, observer.h. (gdbpy_auto_load): New global. (gdbpy_current_objfile): Likewise. (GDBPY_AUTO_FILENAME): New define. (gdbpy_new_objfile): New function. (gdbpy_get_current_objfile): Likewise. (gdbpy_objfiles): Likewise. (_initialize_python): Add "maint set auto-load". Call gdbpy_initialize_objfile. Attach objfile observer. (GdbMethods): New methods current_objfile, objfiles. * python/python-objfile.c: New file. * python/python-internal.h (objfile_to_objfile_object): Declare. (objfpy_get_printers): Likewise. (gdbpy_initialize_objfile): Likewise. * Makefile.in (SUBDIR_PYTHON_OBS): Add python-objfile.o. (SUBDIR_PYTHON_SRCS): Add python-objfile.c. (python-objfile.o): New target. 2009-04-01 Tom Tromey Thiago Jung Bauermann Phil Muldoon * gdb.texinfo: Add @syncodeindex for `tp'. (Python API): Update. (Auto-loading): New node. (Objfiles In Python): New node. 2009-04-06 Tom Tromey * gdb.python/python.exp (gdb_py_test_multiple): Add two objfile tests. * gdb.python/python-value.exp (py_objfile_tests): New proc. Call it. --- gdb/ChangeLog | 22 +++ gdb/Makefile.in | 6 + gdb/doc/ChangeLog | 9 + gdb/doc/gdb.texinfo | 94 ++++++++++++ gdb/python/python-internal.h | 4 + gdb/python/python-objfile.c | 229 +++++++++++++++++++++++++++++ gdb/python/python.c | 146 ++++++++++++++++++ gdb/testsuite/ChangeLog | 7 + gdb/testsuite/gdb.python/python-value.exp | 10 ++ gdb/testsuite/gdb.python/python.exp | 3 + 10 files changed, 530 insertions(+), 0 deletions(-) create mode 100644 gdb/python/python-objfile.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 6b69881..dbd2126 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -267,12 +267,14 @@ SUBDIR_PYTHON_OBS = \ python.o \ python-cmd.o \ python-function.o \ + python-objfile.o \ python-utils.o \ python-value.o SUBDIR_PYTHON_SRCS = \ python/python.c \ python/python-cmd.c \ python/python-function.c \ + python/python-objfile.c \ python/python-utils.c \ python/python-value.c SUBDIR_PYTHON_DEPS = @@ -1851,6 +1853,10 @@ python-function.o: $(srcdir)/python/python-function.c $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-function.c $(POSTCOMPILE) +python-objfile.o: $(srcdir)/python/python-objfile.c + $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-objfile.c + $(POSTCOMPILE) + python-utils.o: $(srcdir)/python/python-utils.c $(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-utils.c $(POSTCOMPILE) diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index dd26db8..ca3c99b 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -21,6 +21,7 @@ @finalout @syncodeindex ky cp +@syncodeindex tp cp @c readline appendices use @vindex, @findex and @ftable, @c annotate.texi and gdbmi use @findex. @@ -18222,9 +18223,11 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown. @menu * Basic Python:: Basic Python Functions. * Exception Handling:: +* Auto-loading:: Automatically loading Python code. * Values From Inferior:: * Commands In Python:: Implementing new commands in Python. * Functions In Python:: Writing new convenience functions. +* Objfiles In Python:: Object files. @end menu @node Basic Python @@ -18322,6 +18325,53 @@ message as its value, and the Python call stack backtrace at the Python statement closest to where the @value{GDBN} error occured as the traceback. +@node Auto-loading +@subsubsection Auto-loading +@cindex auto-loading, Python + +When a new object file is read (for example, due to the @code{file} +command, or because the inferior has loaded a shared library), +@value{GDBN} will look for a file named @file{@var{objfile}-gdb.py}, +where @var{objfile} is the object file's real name, formed by ensuring +that the file name is absolute, following all symlinks, and resolving +@code{.} and @code{..} components. If this file exists and is +readable, @value{GDBN} will evaluate it as a Python script. + +If this file does not exist, and if the parameter +@code{debug-file-directory} is set (@pxref{Separate Debug Files}), +then @value{GDBN} will use the file named +@file{@var{debug-file-directory}/@var{real-name}}, where +@var{real-name} is the object file's real name, as described above. + +Finally, if this file does not exist, then @value{GDBN} will look for +a file named @file{@var{data-directory}/python/auto-load/@var{real-name}}, where +@var{data-directory} is @value{GDBN}'s data directory (available via +@code{show data-directory}, @pxref{Data Files}), and @var{real-name} +is the object file's real name, as described above. + +When reading an auto-loaded file, @value{GDBN} sets the ``current +objfile''. This is available via the @code{gdb.current_objfile} +function (@pxref{Objfiles In Python}). This can be useful for +registering objfile-specific pretty-printers. + +The auto-loading feature is useful for supplying application-specific +debugging commands and scripts. You can enable or disable this +feature, and view its current state. + +@table @code +@kindex maint set python auto-load +@item maint set python auto-load [yes|no] +Enable or disable the Python auto-loading feature. + +@kindex show python auto-load +@item show python auto-load +Show whether Python auto-loading is enabled or disabled. +@end table + +@value{GDBN} does not track which files it has already auto-loaded. +So, your @samp{-gdb.py} file should take care to ensure that it may be +evaluated multiple times without error. + @node Values From Inferior @subsubsection Values From Inferior @cindex values from inferior, with Python @@ -18735,6 +18785,50 @@ registration of the function with @value{GDBN}. Depending on how the Python code is read into @value{GDBN}, you may need to import the @code{gdb} module explicitly. +@node Objfiles In Python +@subsubsection Objfiles In Python + +@cindex objfiles in python +@tindex gdb.Objfile +@tindex Objfile +@value{GDBN} loads symbols for an inferior from various +symbol-containing files (@pxref{Files}). These include the primary +executable file, any shared libraries used by the inferior, and any +separate debug info files (@pxref{Separate Debug Files}). +@value{GDBN} calls these symbol-containing files @dfn{objfiles}. + +The following objfile-related functions are available in the +@code{gdb} module: + +@findex gdb.current_objfile +@defun current_objfile +When auto-loading a Python script (@pxref{Auto-loading}), @value{GDBN} +sets the ``current objfile'' to the corresponding objfile. This +function returns the current objfile. If there is no current objfile, +this function returns @code{None}. +@end defun + +@findex gdb.objfiles +@defun objfiles +Return a sequence of all the objfiles current known to @value{GDBN}. +@xref{Objfiles In Python}. +@end defun + +Each objfile is represented by an instance of the @code{gdb.Objfile} +class. + +@defivar Objfile filename +The file name of the objfile as a string. +@end defivar + +@defivar Objfile pretty_printers +The @code{pretty_printers} attribute is a list of functions. It is +used to look up pretty-printers. A @code{Value} is passed to each +function in order; if the function returns @code{None}, then the +search continues. Otherwise, the return value should be an object +which is used to format the value. +@end defivar + @node Interpreters @chapter Command Interpreters @cindex command interpreters diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 463f08e..9764f4f 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -66,12 +66,16 @@ extern PyTypeObject value_object_type; PyObject *gdbpy_history (PyObject *self, PyObject *args); PyObject *value_to_value_object (struct value *v); +PyObject *objfile_to_objfile_object (struct objfile *); + +PyObject *objfpy_get_printers (PyObject *, void *); struct value *convert_value_from_python (PyObject *obj); void gdbpy_initialize_values (void); void gdbpy_initialize_commands (void); void gdbpy_initialize_functions (void); +void gdbpy_initialize_objfile (void); struct cleanup *make_cleanup_py_decref (PyObject *py); struct cleanup *make_cleanup_py_restore_gil (PyGILState_STATE *state); diff --git a/gdb/python/python-objfile.c b/gdb/python/python-objfile.c new file mode 100644 index 0000000..b70a006 --- /dev/null +++ b/gdb/python/python-objfile.c @@ -0,0 +1,229 @@ +/* Python interface to objfiles. + + Copyright (C) 2008, 2009 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "python-internal.h" +#include "charset.h" +#include "objfiles.h" + +typedef struct +{ + PyObject_HEAD + + /* The corresponding objfile. */ + struct objfile *objfile; + + /* The pretty-printer list of functions. */ + PyObject *printers; +} objfile_object; + +static PyTypeObject objfile_object_type; + +static const struct objfile_data *objfpy_objfile_data_key; + + + +/* An Objfile method which returns the objfile's file name, or None. */ +static PyObject * +objfpy_get_filename (PyObject *self, void *closure) +{ + objfile_object *obj = (objfile_object *) self; + if (obj->objfile && obj->objfile->name) + return PyString_Decode (obj->objfile->name, strlen (obj->objfile->name), + host_charset (), NULL); + Py_RETURN_NONE; +} + +static void +objfpy_dealloc (PyObject *o) +{ + objfile_object *self = (objfile_object *) o; + Py_XDECREF (self->printers); + self->ob_type->tp_free ((PyObject *) self); +} + +static PyObject * +objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords) +{ + objfile_object *self = (objfile_object *) type->tp_alloc (type, 0); + if (self) + { + self->objfile = NULL; + + self->printers = PyList_New (0); + if (!self->printers) + { + Py_DECREF (self); + return NULL; + } + } + return (PyObject *) self; +} + +PyObject * +objfpy_get_printers (PyObject *o, void *ignore) +{ + objfile_object *self = (objfile_object *) o; + Py_INCREF (self->printers); + return self->printers; +} + +static int +objfpy_set_printers (PyObject *o, PyObject *value, void *ignore) +{ + PyObject *tmp; + objfile_object *self = (objfile_object *) o; + if (! value) + { + PyErr_SetString (PyExc_TypeError, + "cannot delete the pretty_printers attribute"); + return -1; + } + + if (! PyList_Check (value)) + { + PyErr_SetString (PyExc_TypeError, + "the pretty_printers attribute must be a list"); + return -1; + } + + /* Take care in case the LHS and RHS are related somehow. */ + tmp = self->printers; + Py_INCREF (value); + self->printers = value; + Py_XDECREF (tmp); + + return 0; +} + + + +/* Clear the OBJFILE pointer in an Objfile object and remove the + reference. */ +static void +clean_up_objfile (struct objfile *objfile, void *datum) +{ + PyGILState_STATE state; + objfile_object *object = datum; + + state = PyGILState_Ensure (); + object->objfile = NULL; + Py_DECREF ((PyObject *) object); + PyGILState_Release (state); +} + +/* Return a borrowed reference to the Python object of type Objfile + representing OBJFILE. If the object has already been created, + return it. Otherwise, create it. Return NULL and set the Python + error on failure. */ +PyObject * +objfile_to_objfile_object (struct objfile *objfile) +{ + objfile_object *object; + + object = objfile_data (objfile, objfpy_objfile_data_key); + if (!object) + { + object = PyObject_New (objfile_object, &objfile_object_type); + if (object) + { + PyObject *dict; + + object->objfile = objfile; + + object->printers = PyList_New (0); + if (!object->printers) + { + Py_DECREF (object); + return NULL; + } + + set_objfile_data (objfile, objfpy_objfile_data_key, object); + } + } + + return (PyObject *) object; +} + +void +gdbpy_initialize_objfile (void) +{ + objfpy_objfile_data_key + = register_objfile_data_with_cleanup (clean_up_objfile); + + if (PyType_Ready (&objfile_object_type) < 0) + return; + + Py_INCREF (&objfile_object_type); + PyModule_AddObject (gdb_module, "Objfile", (PyObject *) &objfile_object_type); +} + + + +static PyGetSetDef objfile_getset[] = +{ + { "filename", objfpy_get_filename, NULL, + "The objfile's filename, or None.", NULL }, + { "pretty_printers", objfpy_get_printers, objfpy_set_printers, + "Pretty printers.", NULL }, + { NULL } +}; + +static PyTypeObject objfile_object_type = +{ + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ + "gdb.Objfile", /*tp_name*/ + sizeof (objfile_object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + objfpy_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "GDB objfile object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + objfile_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + objfpy_new, /* tp_new */ +}; diff --git a/gdb/python/python.c b/gdb/python/python.c index b48cf05..fcf351f 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -22,6 +22,8 @@ #include "ui-out.h" #include "cli/cli-script.h" #include "gdbcmd.h" +#include "objfiles.h" +#include "observer.h" #include @@ -29,6 +31,10 @@ false otherwise. */ static int gdbpy_should_print_stack = 1; +/* This is true if we should auto-load python code when an objfile is + opened, false otherwise. */ +static int gdbpy_auto_load = 1; + #ifdef HAVE_PYTHON #include "python.h" @@ -301,6 +307,129 @@ gdbpy_print_stack (void) PyErr_Clear (); } + + +/* The "current" objfile. This is set when gdb detects that a new + objfile has been loaded. It is only set for the duration of a call + to gdbpy_new_objfile; it is NULL at other times. */ +static struct objfile *gdbpy_current_objfile; + +/* The file name we attempt to read. */ +#define GDBPY_AUTO_FILENAME "-gdb.py" + +/* This is a new_objfile observer callback which loads python code + based on the path to the objfile. */ +static void +gdbpy_new_objfile (struct objfile *objfile) +{ + char *realname; + char *filename, *debugfile; + int len; + FILE *input; + PyGILState_STATE state; + struct cleanup *cleanups; + + if (!gdbpy_auto_load || !objfile || !objfile->name) + return; + + state = PyGILState_Ensure (); + + gdbpy_current_objfile = objfile; + + realname = gdb_realpath (objfile->name); + len = strlen (realname); + filename = xmalloc (len + sizeof (GDBPY_AUTO_FILENAME)); + memcpy (filename, realname, len); + strcpy (filename + len, GDBPY_AUTO_FILENAME); + + input = fopen (filename, "r"); + debugfile = filename; + + cleanups = make_cleanup (xfree, filename); + make_cleanup (xfree, realname); + + if (!input && debug_file_directory) + { + /* Also try the same file in the separate debug info directory. */ + debugfile = xmalloc (strlen (filename) + + strlen (debug_file_directory) + 1); + strcpy (debugfile, debug_file_directory); + /* FILENAME is absolute, so we don't need a "/" here. */ + strcat (debugfile, filename); + + make_cleanup (xfree, debugfile); + input = fopen (debugfile, "r"); + } + + if (!input && gdb_datadir) + { + /* Also try the same file in a subdirectory of gdb's data + directory. */ + debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename) + + strlen ("/auto-load") + 1); + strcpy (debugfile, gdb_datadir); + strcat (debugfile, "/auto-load"); + /* FILENAME is absolute, so we don't need a "/" here. */ + strcat (debugfile, filename); + + make_cleanup (xfree, debugfile); + input = fopen (debugfile, "r"); + } + + if (input) + { + /* We don't want to throw an exception here -- but the user + would like to know that something went wrong. */ + if (PyRun_SimpleFile (input, debugfile)) + gdbpy_print_stack (); + fclose (input); + } + + do_cleanups (cleanups); + gdbpy_current_objfile = NULL; + + PyGILState_Release (state); +} + +/* Return the current Objfile, or None if there isn't one. */ +static PyObject * +gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2) +{ + PyObject *result; + + if (! gdbpy_current_objfile) + Py_RETURN_NONE; + + result = objfile_to_objfile_object (gdbpy_current_objfile); + if (result) + Py_INCREF (result); + return result; +} + +/* Return a sequence holding all the Objfiles. */ +static PyObject * +gdbpy_objfiles (PyObject *unused1, PyObject *unused2) +{ + struct objfile *objf; + PyObject *list; + + list = PyList_New (0); + if (!list) + return NULL; + + ALL_OBJFILES (objf) + { + PyObject *item = objfile_to_objfile_object (objf); + if (!item || PyList_Append (list, item) == -1) + { + Py_DECREF (list); + return NULL; + } + } + + return list; +} + #else /* HAVE_PYTHON */ /* Dummy implementation of the gdb "python" command. */ @@ -399,6 +528,15 @@ Enables or disables printing of Python stack traces."), &set_python_list, &show_python_list); + add_setshow_boolean_cmd ("auto-load", class_maintenance, + &gdbpy_auto_load, _("\ +Enable or disable auto-loading of Python code when an object is opened."), _("\ +Show whether Python code will be auto-loaded when an object is opened."), _("\ +Enables or disables auto-loading of Python code when an object is opened."), + NULL, NULL, + &set_python_list, + &show_python_list); + #ifdef HAVE_PYTHON Py_Initialize (); PyEval_InitThreads (); @@ -413,9 +551,12 @@ Enables or disables printing of Python stack traces."), gdbpy_initialize_values (); gdbpy_initialize_commands (); gdbpy_initialize_functions (); + gdbpy_initialize_objfile (); PyRun_SimpleString ("import gdb"); + observer_attach_new_objfile (gdbpy_new_objfile); + gdbpy_doc_cst = PyString_FromString ("__doc__"); /* Create a couple objects which are used for Python's stdout and @@ -464,6 +605,11 @@ static PyMethodDef GdbMethods[] = { "get_parameter", get_parameter, METH_VARARGS, "Return a gdb parameter's value" }, + { "current_objfile", gdbpy_get_current_objfile, METH_NOARGS, + "Return the current Objfile being loaded, or None." }, + { "objfiles", gdbpy_objfiles, METH_NOARGS, + "Return a sequence of all loaded objfiles." }, + { "write", gdbpy_write, METH_VARARGS, "Write a string using gdb's filtered stream." }, { "flush", gdbpy_flush, METH_NOARGS, diff --git a/gdb/testsuite/gdb.python/python-value.exp b/gdb/testsuite/gdb.python/python-value.exp index b3b5746..93e9d89 100644 --- a/gdb/testsuite/gdb.python/python-value.exp +++ b/gdb/testsuite/gdb.python/python-value.exp @@ -236,6 +236,15 @@ proc test_value_in_inferior {} { gdb_test "python print 'result =', arg0.address" "= 0x\[\[:xdigit:\]\]+" "Test address attribute" } +# A few objfile tests. +proc test_objfiles {} { + gdb_test "python\nok=False\nfor file in gdb.objfiles():\n if 'python-value' in file.filename:\n ok=True\nprint ok\nend" "True" + + gdb_test "python print gdb.objfiles()\[0\].pretty_printers" "\\\[\\\]" + + gdb_test "python gdb.objfiles()\[0\].pretty_printers = 0" \ + "pretty_printers attribute must be a list.*Error while executing Python code." +} # Start with a fresh gdb. @@ -256,6 +265,7 @@ test_value_creation test_value_numeric_ops test_value_boolean test_value_compare +test_objfiles # The following tests require execution. diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp index a0c9b39..5223fc8 100644 --- a/gdb/testsuite/gdb.python/python.exp +++ b/gdb/testsuite/gdb.python/python.exp @@ -71,3 +71,6 @@ gdb_py_test_multiple "indented multi-line python command" \ " print 'hello, world!'" "" \ "foo ()" "" \ "end" "hello, world!" + +gdb_test "python print gdb.current_objfile()" "None" +gdb_test "python print gdb.objfiles()" "\\\[\\\]" -- 1.6.0.6