From patchwork Tue Oct 15 16:46:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 34987 Received: (qmail 69560 invoked by alias); 15 Oct 2019 16:46:55 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 69536 invoked by uid 89); 15 Oct 2019 16:46:55 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=H*m:andrew X-HELO: mail-wm1-f45.google.com Received: from mail-wm1-f45.google.com (HELO mail-wm1-f45.google.com) (209.85.128.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 15 Oct 2019 16:46:53 +0000 Received: by mail-wm1-f45.google.com with SMTP id 7so21658047wme.1 for ; Tue, 15 Oct 2019 09:46:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=uagaQE10zZPavxGqmkHD54RLV23pno/abAx5kNbikqo=; b=H0ybWYwS0lAeX6m8+5u2cBxf44OMxLD+ZDWRcYn8flAVcNHbnyWV4UhdwEML8I8B+k m9vnDD7wwrz4LIc08M73gx/4eHI1Zu1yYuOxGXvoUulAOsGsEEj6tz9YaPg/B5Anvv/g KA58lMowuMY/dhVY+5kWn8IBIYnZ0F/nD5rAdnwkaHMK2P/DuIz+hRBAurE4P9j+gCzS rGz1Kur7u0BghYjtLKPfL9VM2XhuxRS6TeXSkj1k7xQwbSQh7mlyuquWzz1nuyfXp0v2 ZpFld6hSSIKKT35jy7DtAEntgcpUJx0iIsu0z1KiVOmzzBYyiu5ussUQWeS6HxeAJH4S dxcA== Return-Path: Received: from localhost (host86-128-12-122.range86-128.btcentralplus.com. [86.128.12.122]) by smtp.gmail.com with ESMTPSA id h17sm36650105wme.6.2019.10.15.09.46.49 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 15 Oct 2019 09:46:49 -0700 (PDT) From: Andrew Burgess To: gdb-patches Cc: Christian Biesinger , Andrew Burgess Subject: [PATCH] gdb/python: Introduce gdb.lookup_all_static_symbols Date: Tue, 15 Oct 2019 17:46:47 +0100 Message-Id: <20191015164647.1837-1-andrew.burgess@embecosm.com> In-Reply-To: <20191015141515.GW4962@embecosm.com> References: <20191015141515.GW4962@embecosm.com> X-IsSubscribed: yes If gdb.lookup_static_symbol is going to return a single symbol then it makes sense (I think) for it to return a context sensitive choice of symbol, that is the static symbol that would be visible to the program at that point. However, if the user of the python API wants to instead get a consistent set of static symbols, no matter where they stop, then they have to instead consider all static symbols with a given name - there could be many. That is what this new API function offers, it returns a list (possibly empty) of all static symbols matching a given name (and optionally a given symbol domain). gdb/ChangeLog: * python/py-symbol.c (gdbpy_lookup_all_static_symbols): New function. * python/python-internal.h (gdbpy_lookup_all_static_symbols): Declare new function. * python/python.c (python_GdbMethods): Add gdb.lookup_all_static_symbols method. gdb/testsuite/ChangeLog: * gdb.python/py-symbol.exp: Add test for gdb.lookup_all_static_symbols. gdb/doc/ChangeLog: * python.texi (Symbols In Python): Add documentation for gdb.lookup_all_static_symbols. Change-Id: I1153b0ae5bcbc43b3dcf139043c7a48bf791e1a3 --- gdb/ChangeLog | 9 ++++++ gdb/doc/ChangeLog | 5 +++ gdb/doc/python.texi | 35 +++++++++++++++++++++ gdb/python/py-symbol.c | 56 ++++++++++++++++++++++++++++++++++ gdb/python/python-internal.h | 2 ++ gdb/python/python.c | 4 +++ gdb/testsuite/ChangeLog | 5 +++ gdb/testsuite/gdb.python/py-symbol.exp | 8 +++++ 8 files changed, 124 insertions(+) diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 0f12de94bba..2126effa12f 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -4880,6 +4880,41 @@ information. @end defun +@findex gdb.lookup_global_symbol +@defun gdb.lookup_global_symbol (name @r{[}, domain@r{]}) +This function searches for a global symbol by name. +The search scope can be restricted to by the domain argument. + +@var{name} is the name of the symbol. It must be a string. +The optional @var{domain} argument restricts the search to the domain type. +The @var{domain} argument must be a domain constant defined in the @code{gdb} +module and described later in this chapter. + +The result is a @code{gdb.Symbol} object or @code{None} if the symbol +is not found. +@end defun + +@findex gdb.lookup_all_static_symbols +@defun gdb.lookup_all_static_symbols (name @r{[}, domain@r{]}) +Similar to @code{gdb.lookup_static_symbol}, this function searches for +global symbols with static linkage by name, and optionally restricted +by the domain argument. However, this function returns a list of all +matching symbols found, not just the first one. + +@var{name} is the name of the symbol. It must be a string. +The optional @var{domain} argument restricts the search to the domain type. +The @var{domain} argument must be a domain constant defined in the @code{gdb} +module and described later in this chapter. + +The result is a list of @code{gdb.Symbol} objects which could be empty +if no matching symbols were found. + +Note that this function will not find function-scoped static variables. To look +up such variables, iterate over the variables of the function's +@code{gdb.Block} and check that @code{block.addr_class} is +@code{gdb.SYMBOL_LOC_STATIC}. +@end defun + A @code{gdb.Symbol} object has the following attributes: @defvar Symbol.type diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c index ae9aca6c5d0..6e126f9f377 100644 --- a/gdb/python/py-symbol.c +++ b/gdb/python/py-symbol.c @@ -534,6 +534,62 @@ gdbpy_lookup_static_symbol (PyObject *self, PyObject *args, PyObject *kw) return sym_obj; } +/* Implementation of + gdb.lookup_all_static_symbols (name [, domain) -> [symbol] or None. + + Returns a list of all static symbols matching NAME in DOMAIN. */ + +PyObject * +gdbpy_lookup_all_static_symbols (PyObject *self, PyObject *args, PyObject *kw) +{ + const char *name; + int domain = VAR_DOMAIN; + static const char *keywords[] = { "name", "domain", NULL }; + + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &name, + &domain)) + return NULL; + + gdbpy_ref<> return_list (PyList_New (0)); + if (return_list == NULL) + return NULL; + + try + { + for (objfile *objfile : current_program_space->objfiles ()) + { + for (compunit_symtab *cust : objfile->compunits ()) + { + const struct blockvector *bv; + const struct block *block; + + bv = COMPUNIT_BLOCKVECTOR (cust); + block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + + if (block != nullptr) + { + symbol *symbol = lookup_symbol_in_static_block + (name, block, (domain_enum) domain).symbol; + + if (symbol != nullptr) + { + PyObject *sym_obj + = symbol_to_symbol_object (symbol); + if (PyList_Append (return_list.get (), sym_obj) == -1) + return NULL; + } + } + } + } + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + + return return_list.release (); +} + /* This function is called when an objfile is about to be freed. Invalidate the symbol as further actions on the symbol would result in bad data. All access to obj->symbol should be gated by diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index c5578430cff..e29e018a9d8 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -426,6 +426,8 @@ PyObject *gdbpy_lookup_global_symbol (PyObject *self, PyObject *args, PyObject *kw); PyObject *gdbpy_lookup_static_symbol (PyObject *self, PyObject *args, PyObject *kw); +PyObject *gdbpy_lookup_all_static_symbols (PyObject *self, PyObject *args, + PyObject *kw); PyObject *gdbpy_start_recording (PyObject *self, PyObject *args); PyObject *gdbpy_current_recording (PyObject *self, PyObject *args); PyObject *gdbpy_stop_recording (PyObject *self, PyObject *args); diff --git a/gdb/python/python.c b/gdb/python/python.c index ddf0e72d26f..80936e2ab7b 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1994,6 +1994,10 @@ Return the symbol corresponding to the given name (or None)." }, METH_VARARGS | METH_KEYWORDS, "lookup_static_symbol (name [, domain]) -> symbol\n\ Return the static-linkage symbol corresponding to the given name (or None)." }, + { "lookup_all_static_symbols", (PyCFunction) gdbpy_lookup_all_static_symbols, + METH_VARARGS | METH_KEYWORDS, + "lookup_all_static_symbols (name [, domain]) -> symbol\n\ +Return a list of all static-linkage symbols corresponding to the given name." }, { "lookup_objfile", (PyCFunction) gdbpy_lookup_objfile, METH_VARARGS | METH_KEYWORDS, diff --git a/gdb/testsuite/gdb.python/py-symbol.exp b/gdb/testsuite/gdb.python/py-symbol.exp index 61960075565..116c32441f8 100644 --- a/gdb/testsuite/gdb.python/py-symbol.exp +++ b/gdb/testsuite/gdb.python/py-symbol.exp @@ -108,6 +108,10 @@ gdb_breakpoint "function_in_other_file" gdb_continue_to_breakpoint "function_in_other_file" gdb_test "python print (gdb.lookup_static_symbol ('rr').value ())" "99" \ "print value of rr from other file" +gdb_test "python print (gdb.lookup_all_static_symbols ('rr')\[0\].value ())" "99" \ + "print value of gdb.lookup_all_static_symbols ('rr')\[0\], from the other file" +gdb_test "python print (gdb.lookup_all_static_symbols ('rr')\[1\].value ())" "42" \ + "print value of gdb.lookup_all_static_symbols ('rr')\[1\], from the other file" # Now continue back to the first source file. set linenum [gdb_get_line_number "Break at end."] @@ -119,6 +123,10 @@ gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0 # static symbol from the second source file. gdb_test "python print (gdb.lookup_static_symbol ('rr').value ())" "42" \ "print value of rr from main file" +gdb_test "python print (gdb.lookup_all_static_symbols ('rr')\[0\].value ())" "99" \ + "print value of gdb.lookup_all_static_symbols ('rr')\[0\], from the main file" +gdb_test "python print (gdb.lookup_all_static_symbols ('rr')\[1\].value ())" "42" \ + "print value of gdb.lookup_all_static_symbols ('rr')\[1\], from the main file" # Test is_variable attribute. gdb_py_test_silent_cmd "python a = gdb.lookup_symbol(\'a\')" "Get variable a" 0