Re: [PATCH v4] Add Objfile.lookup_{global,static}_symbol functions

Simon Marchi
2019-07-30T01:03:40Z

On 2019-07-27 2:30 p.m., Christian Biesinger via gdb-patches wrote:
> Thanks Eli, fixed in this version.
>
> This is essentially the inverse of Symbol.objfile. This allows
> handling different symbols with the same name (but from different
> objfiles) and can also be faster if the objfile is known.
>
> gdb/ChangeLog:
>
> 2019-07-25 Christian Biesinger <cbiesinger@google.com>
>
> * NEWS: Mention new functions Objfile.lookup_{global,static}_symbol.
> * python/py-objfile.c (objfpy_lookup_global_symbol): New function.
> (objfpy_lookup_static_symbol): New function.
> (objfile_object_methods): Add new functions.
>
> gdb/doc/ChangeLog:
>
> 2019-07-25 Christian Biesinger <cbiesinger@google.com>
>
> * python.texi (Objfiles In Python): Document new functions
> Objfile.lookup_{global,static}_symbol.
>
> gdb/testsuite/ChangeLog:
>
> 2019-07-25 Christian Biesinger <cbiesinger@google.com>
>
> * gdb.python/py-objfile.c: Add global and static vars.
> * gdb.python/py-objfile.exp: Test new functions Objfile.
> lookup_global_symbol and lookup_static_symbol.
> ---
> gdb/NEWS | 3 +
> gdb/doc/python.texi | 17 ++++++
> gdb/python/py-objfile.c | 78 +++++++++++++++++++++++++
> gdb/testsuite/gdb.python/py-objfile.c | 3 +
> gdb/testsuite/gdb.python/py-objfile.exp | 14 +++++
> 5 files changed, 115 insertions(+)
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index cc1d58520d..d8fb4cfe7f 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -36,6 +36,9 @@
> ** gdb.Type has a new property 'objfile' which returns the objfile the
> type was defined in.
>
> + ** gdb.Objfile has new methods 'lookup_global_symbol' and
> + 'lookup_static_symbol' to lookup a symbol from this objfile only.
> +
> * New commands
>
> | [COMMAND] | SHELL_COMMAND
> diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
> index 034623513b..bbba519ffc 100644
> --- a/gdb/doc/python.texi
> +++ b/gdb/doc/python.texi
> @@ -4441,6 +4441,23 @@ searches then this function can be used to add a debug info file
> from a different place.
> @end defun
>
> +@defun Objfile.lookup_global_symbol (name @r{[}, domain@r{]})
> +Search for a global symbol named @var{name} in this objfile. Optionally, the
> +search scope can be restricted with the @var{domain} argument.
> +The @var{domain} argument must be a domain constant defined in the @code{gdb}
> +module and described in @ref{Symbols In Python}. This function is similar to
> +@code{gdb.lookup_global_symbol}, except that the search is limited to this
> +objfile.
> +
> +The result is a @code{gdb.Symbol} object or @code{None} if the symbol
> +is not found.
> +@end defun
> +
> +@defun Objfile.lookup_static_symbol (name @r{[}, domain@r{]})
> +Like @code{Objfile.lookup_global_symbol}, but searches for a global
> +symbol with static linkage named @var{name} in this objfile.
> +@end defun
> +
> @node Frames In Python
> @subsubsection Accessing inferior stack frames from Python
>
> diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
> index 15735c8501..2c548450b4 100644
> --- a/gdb/python/py-objfile.c
> +++ b/gdb/python/py-objfile.c
> @@ -434,6 +434,74 @@ objfpy_add_separate_debug_file (PyObject *self, PyObject *args, PyObject *kw)
> Py_RETURN_NONE;
> }
>
> +/* Implementation of
> + gdb.Objfile.lookup_global_symbol (self, string [, domain]) -> gdb.Symbol. */
> +
> +static PyObject *
> +objfpy_lookup_global_symbol (PyObject *self, PyObject *args, PyObject *kw)
> +{
> + static const char *keywords[] = { "name", "domain", NULL };
> + objfile_object *obj = (objfile_object *) self;
> + const char *symbol_name;
> + int domain = VAR_DOMAIN;
> +
> + OBJFPY_REQUIRE_VALID (obj);
> +
> + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &symbol_name,
> + &domain))
> + return nullptr;
> +
> + try
> + {
> + struct symbol *sym = lookup_global_symbol_from_objfile
> + (obj->objfile, GLOBAL_BLOCK, symbol_name, (domain_enum) domain).symbol;
> + if (sym == nullptr)
> + Py_RETURN_NONE;
> +
> + return symbol_to_symbol_object (sym);
> + }
> + catch (const gdb_exception &except)
> + {
> + GDB_PY_HANDLE_EXCEPTION (except);
> + }
> +
> + Py_RETURN_NONE;
> +}
> +
> +/* Implementation of
> + gdb.Objfile.lookup_static_symbol (self, string [, domain]) -> gdb.Symbol. */
> +
> +static PyObject *
> +objfpy_lookup_static_symbol (PyObject *self, PyObject *args, PyObject *kw)
> +{
> + static const char *keywords[] = { "name", "domain", NULL };
> + objfile_object *obj = (objfile_object *) self;
> + const char *symbol_name;
> + int domain = VAR_DOMAIN;
> +
> + OBJFPY_REQUIRE_VALID (obj);
> +
> + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &symbol_name,
> + &domain))
> + return nullptr;
> +
> + try
> + {
> + struct symbol *sym = lookup_global_symbol_from_objfile
> + (obj->objfile, STATIC_BLOCK, symbol_name, (domain_enum) domain).symbol;
> + if (sym == nullptr)
> + Py_RETURN_NONE;
> +
> + return symbol_to_symbol_object (sym);
> + }
> + catch (const gdb_exception &except)
> + {
> + GDB_PY_HANDLE_EXCEPTION (except);
> + }
> +
> + Py_RETURN_NONE;
> +}
> +
> /* Implement repr() for gdb.Objfile. */
>
> static PyObject *
> @@ -652,6 +720,16 @@ Return true if this object file is valid, false if not." },
> "add_separate_debug_file (file_name).\n\
> Add FILE_NAME to the list of files containing debug info for the objfile." },
>
> + { "lookup_global_symbol", (PyCFunction) objfpy_lookup_global_symbol,
> + METH_VARARGS | METH_KEYWORDS,
> + "lookup_global_symbol (name [, domain]).\n\
> +Look up a global symbol in this objfile and return it." },
> +
> + { "lookup_static_symbol", (PyCFunction) objfpy_lookup_static_symbol,
> + METH_VARARGS | METH_KEYWORDS,
> + "lookup_static_symbol (name [, domain]).\n\
> +Look up a static-linkage global symbol in this objfile and return it." },
> +
> { NULL }
> };
>
> diff --git a/gdb/testsuite/gdb.python/py-objfile.c b/gdb/testsuite/gdb.python/py-objfile.c
> index ac41491234..6d751bddae 100644
> --- a/gdb/testsuite/gdb.python/py-objfile.c
> +++ b/gdb/testsuite/gdb.python/py-objfile.c
> @@ -15,6 +15,9 @@
> You should have received a copy of the GNU General Public License
> along with this program. If not, see <http://www.gnu.org/licenses/>. */
>
> +int global_var = 42;
> +static int static_var = 50;
> +
> int
> main ()
> {
> diff --git a/gdb/testsuite/gdb.python/py-objfile.exp b/gdb/testsuite/gdb.python/py-objfile.exp
> index b5e0c5e760..1b8acf47ed 100644
> --- a/gdb/testsuite/gdb.python/py-objfile.exp
> +++ b/gdb/testsuite/gdb.python/py-objfile.exp
> @@ -55,6 +55,20 @@ gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").filename)" \
> gdb_test "python print (gdb.lookup_objfile (\"junk\"))" \
> "Objfile not found\\.\r\n${python_error_text}"
>
> +gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_global_symbol (\"global_var\").name)" \
> + "global_var" "lookup_global_symbol finds a valid symbol"
> +gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_global_symbol (\"static_var\")) is None" \
> + "True" "lookup_global_symbol does not find static symbol"
> +gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_global_symbol (\"stdout\"))" \
> + "None" "lookup_global_symbol doesn't find symbol in other objfile"
> +
> +gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_static_symbol (\"static_var\").name)" \
> + "static_var" "lookup_static_symbol finds a valid symbol"
> +gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_static_symbol (\"global_var\")) is None" \
> + "True" "lookup_static_symbol does not find global symbol"
> +gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_static_symbol (\"nonexistant\"))" \
> + "None" "lookup_static_symbol can handle nonexistant symbol"
> +
> set binfile_build_id [get_build_id $binfile]
> if [string compare $binfile_build_id ""] {
> verbose -log "binfile_build_id = $binfile_build_id"
>

Hi Christian,

I get:

$ make check TESTS="gdb.python/py-objfile.exp"
...
FAIL: gdb.python/py-objfile.exp: lookup_global_symbol does not find static symbol
FAIL: gdb.python/py-objfile.exp: lookup_static_symbol does not find global symbol

It's just a typo:

diff --git a/gdb/testsuite/gdb.python/py-objfile.exp b/gdb/testsuite/gdb.python/py-objfile.exp
index 1b8acf47ed52..5f0ac49cad4d 100644
--- a/gdb/testsuite/gdb.python/py-objfile.exp
+++ b/gdb/testsuite/gdb.python/py-objfile.exp
@@ -57,14 +57,14 @@ gdb_test "python print (gdb.lookup_objfile (\"junk\"))" \

gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_global_symbol (\"global_var\").name)" \
"global_var" "lookup_global_symbol finds a valid symbol"
-gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_global_symbol (\"static_var\")) is None" \
+gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_global_symbol (\"static_var\") is None)" \
"True" "lookup_global_symbol does not find static symbol"
gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_global_symbol (\"stdout\"))" \
"None" "lookup_global_symbol doesn't find symbol in other objfile"

gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_static_symbol (\"static_var\").name)" \
"static_var" "lookup_static_symbol finds a valid symbol"
-gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_static_symbol (\"global_var\")) is None" \
+gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_static_symbol (\"global_var\") is None)" \
"True" "lookup_static_symbol does not find global symbol"
gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_static_symbol (\"nonexistant\"))" \
"None" "lookup_static_symbol can handle nonexistant symbol"
---

The patch LGTM, please push with this fixed.

Simon