From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <andrew.burgess@embecosm.com>
Subject: Re: [PATCHv3] gdb/python: add gdb.format_address function
Date: Mon, 21 Mar 2022 17:53:17 +0000 [thread overview]
Message-ID: <87v8w7ry42.fsf@redhat.com> (raw)
In-Reply-To: <20220307123317.3966024-1-aburgess@redhat.com>
Ping!
Thanks,
Andrew
Andrew Burgess <aburgess@redhat.com> writes:
> From: Andrew Burgess <andrew.burgess@embecosm.com>
>
> Since v2:
>
> - Almost complete rewrite, function is now gdb.format_address, and
> takes an address, program space, and architecture,
>
> - Updated docs to go with this,
>
> - Updated tests.
>
> Since v1:
>
> - All the doc changes have been addressed (these have already been
> approved),
>
> - Rebased to current master,
>
> - Added an additional test for when 'set print symbol-filename' is
> on.
>
> Thanks,
> Andrew
>
>
> ---
>
> Add a new function, gdb.format_address, which is a wrapper around
> GDB's print_address function.
>
> This method takes an address, and returns a string with the format:
>
> ADDRESS <SYMBOL+OFFSET>
>
> Where, ADDRESS is the original address, formatted as hexadecimal,
> SYMBOL is a symbol with an address lower than ADDRESS, and OFFSET is
> the offset from SYMBOL to ADDRESS in decimal.
>
> If there's no SYMBOL suitably close to ADDRESS then the
> <SYMBOL+OFFSET> part is not included.
>
> This is useful if a user wants to write a Python script that
> pretty-prints addresses, the user no longer needs to do manual symbol
> lookup, or worry about correctly formatting addresses.
>
> Additionally, there are some settings that effect how GDB picks
> SYMBOL, and whether the file name and line number should be included
> with the SYMBOL name, the gdb.format_address function ensures that the
> users Python script also benefits from these settings.
>
> The gdb.format_address by default selects SYMBOL from the current
> inferiors program space, and address is formatted using the
> architecture for the current inferior. However, a user can also
> explicitly pass a program space and architecture like this:
>
> gdb.format_address(ADDRESS, PROGRAM_SPACE, ARCHITECTURE)
>
> In order to format an address for a different inferior.
>
> Notes on the implementation:
>
> In py-arch.c I extended arch_object_to_gdbarch to add an assertion for
> the type of the PyObject being worked on. Prior to this commit all
> uses of arch_object_to_gdbarch were guaranteed to pass this function a
> gdb.Architecture object, but, with this commit, this might not be the
> case.
>
> So, with this commit I've made it a requirement that the PyObject be a
> gdb.Architecture, and this is checked with the assert. And in order
> that callers from other files can check if they have a
> gdb.Architecture object, I've added the new function
> gdbpy_is_architecture.
>
> In py-progspace.c I've added two new function, the first
> progspace_object_to_program_space, converts a PyObject of type
> gdb.Progspace to the associated program_space pointer, and
> gdbpy_is_progspace checks if a PyObject is a gdb.Progspace or not.
> ---
> gdb/NEWS | 6 +
> gdb/doc/python.texi | 54 ++++++
> gdb/python/py-arch.c | 13 +-
> gdb/python/py-progspace.c | 17 ++
> gdb/python/python-internal.h | 16 ++
> gdb/python/python.c | 108 +++++++++++
> gdb/testsuite/gdb.python/py-format-address.c | 32 ++++
> .../gdb.python/py-format-address.exp | 177 ++++++++++++++++++
> 8 files changed, 421 insertions(+), 2 deletions(-)
> create mode 100644 gdb/testsuite/gdb.python/py-format-address.c
> create mode 100644 gdb/testsuite/gdb.python/py-format-address.exp
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index dc2cac1871b..ec6a0753024 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -206,6 +206,12 @@ GNU/Linux/LoongArch loongarch*-*-linux*
> state information, or None, if there is no such additional
> information.
>
> + ** New function gdb.format_address(ADDRESS, PROGSPACE, ARCHITECTURE),
> + that formats ADDRESS as 'address <symbol+offset>', where symbol is
> + looked up in PROGSPACE, and ARCHITECTURE is used to format address.
> + This is the same format that GDB uses when printing address, symbol,
> + and offset information from the disassembler.
> +
> * New features in the GDB remote stub, GDBserver
>
> ** GDBserver is now supported on OpenRISC GNU/Linux.
> diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
> index 4d9e77bf12c..721c5d3176e 100644
> --- a/gdb/doc/python.texi
> +++ b/gdb/doc/python.texi
> @@ -612,6 +612,60 @@
> connection objects are in no particular order in the returned list.
> @end defun
>
> +@defun gdb.format_address (@var{address} @r{[}, @var{progspace}, @var{architecture}@r{]})
> +Return a string in the format @samp{@var{addr}
> +<@var{symbol}+@var{offset}>}, where @var{addr} is @var{address}
> +formatted in hexadecimal, @var{symbol} is the symbol whose address is
> +the nearest to @var{address} and below it in memory, and @var{offset}
> +is the offset from @var{symbol} to @var{address} in decimal.
> +
> +If no suitable @var{symbol} was found, then the
> +<@var{symbol}+@var{offset}> part is not included in the returned
> +string, instead the returned string will just contain the
> +@var{address} formatted as hexadecimal. How far @value{GDBN} looks
> +back for a suitable symbol can be controlled with @kbd{set print
> +max-symbolic-offset} (@pxref{Print Settings}).
> +
> +Additionally, the returned string can include file name and line
> +number information when @kbd{set print symbol-filename on}
> +(@pxref{Print Settings}), in this case the format of the returned
> +string is @samp{@var{addr} <@var{symbol}+@var{offset}> at
> +@var{filename}:@var{line-number}}.
> +
> +
> +The @var{progspace} is the gdb.Progspace in which @var{symbol} is
> +looked up, and @var{architecture} is used when formatting @var{addr},
> +e.g.@: in order to determine the size of an address in bytes.
> +
> +If neither @var{progspace} or @var{architecture} are passed, then by
> +default @value{GDBN} will use the program space and architecture of
> +the currently selected inferior, thus, the following two calls are
> +equivalent:
> +
> +@smallexample
> +gdb.format_address(address)
> +gdb.format_address(address,
> + gdb.selected_inferior().progspace,
> + gdb.selected_inferior().architecture())
> +@end smallexample
> +
> +It is not valid to only pass one of @var{progspace} or
> +@var{architecture}, either they must both be provided, or neither must
> +be provided (and the defaults will be used).
> +
> +This method uses the same mechanism for formatting address, symbol,
> +and offset information as core @value{GDBN} does in commands such as
> +@kbd{disassemble}.
> +
> +Here are some examples of the possible string formats:
> +
> +@smallexample
> +0x00001042
> +0x00001042 <symbol+16>
> +0x00001042 <symbol+16 at file.c:123>
> +@end smallexample
> +@end defun
> +
> @node Exception Handling
> @subsubsection Exception Handling
> @cindex python exceptions
> diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c
> index 0f273b344e4..53906ce506e 100644
> --- a/gdb/python/py-arch.c
> +++ b/gdb/python/py-arch.c
> @@ -62,16 +62,25 @@ arch_object_data_init (struct gdbarch *gdbarch)
> }
>
> /* Returns the struct gdbarch value corresponding to the given Python
> - architecture object OBJ. */
> + architecture object OBJ, which must be a gdb.Architecture object. */
>
> struct gdbarch *
> arch_object_to_gdbarch (PyObject *obj)
> {
> - arch_object *py_arch = (arch_object *) obj;
> + gdb_assert (PyObject_TypeCheck (obj, &arch_object_type));
>
> + arch_object *py_arch = (arch_object *) obj;
> return py_arch->gdbarch;
> }
>
> +/* See python-internal.h. */
> +
> +bool
> +gdbpy_is_architecture (PyObject *obj)
> +{
> + return PyObject_TypeCheck (obj, &arch_object_type);
> +}
> +
> /* Returns the Python architecture object corresponding to GDBARCH.
> Returns a new reference to the arch_object associated as data with
> GDBARCH. */
> diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c
> index 1e01068c59b..f9f2a969e2b 100644
> --- a/gdb/python/py-progspace.c
> +++ b/gdb/python/py-progspace.c
> @@ -504,6 +504,23 @@ pspace_to_pspace_object (struct program_space *pspace)
> return gdbpy_ref<>::new_reference (result);
> }
>
> +/* See python-internal.h. */
> +
> +struct program_space *
> +progspace_object_to_program_space (PyObject *obj)
> +{
> + gdb_assert (PyObject_TypeCheck (obj, &pspace_object_type));
> + return ((pspace_object *) obj)->pspace;
> +}
> +
> +/* See python-internal.h. */
> +
> +bool
> +gdbpy_is_progspace (PyObject *obj)
> +{
> + return PyObject_TypeCheck (obj, &pspace_object_type);
> +}
> +
> void _initialize_py_progspace ();
> void
> _initialize_py_progspace ()
> diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
> index 5e15f62f745..d2a8e4d8cf4 100644
> --- a/gdb/python/python-internal.h
> +++ b/gdb/python/python-internal.h
> @@ -497,6 +497,13 @@ struct symtab_and_line *sal_object_to_symtab_and_line (PyObject *obj);
> struct frame_info *frame_object_to_frame_info (PyObject *frame_obj);
> struct gdbarch *arch_object_to_gdbarch (PyObject *obj);
>
> +/* Convert Python object OBJ to a program_space pointer. OBJ must be a
> + gdb.Progspace reference. Return nullptr if the gdb.Progspace is not
> + valid (see gdb.Progspace.is_valid), otherwise return the program_space
> + pointer. */
> +
> +extern struct program_space *progspace_object_to_program_space (PyObject *obj);
> +
> void gdbpy_initialize_gdb_readline (void);
> int gdbpy_initialize_auto_load (void)
> CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
> @@ -824,4 +831,13 @@ typedef std::unique_ptr<Py_buffer, Py_buffer_deleter> Py_buffer_up;
> extern bool gdbpy_parse_register_id (struct gdbarch *gdbarch,
> PyObject *pyo_reg_id, int *reg_num);
>
> +/* Return true if OBJ is a gdb.Architecture object, otherwise, return
> + false. */
> +
> +extern bool gdbpy_is_architecture (PyObject *obj);
> +
> +/* Return true if OBJ is a gdb.Progspace object, otherwise, return false. */
> +
> +extern bool gdbpy_is_progspace (PyObject *obj);
> +
> #endif /* PYTHON_PYTHON_INTERNAL_H */
> diff --git a/gdb/python/python.c b/gdb/python/python.c
> index 79f9826365a..8abce819001 100644
> --- a/gdb/python/python.c
> +++ b/gdb/python/python.c
> @@ -1294,6 +1294,107 @@ gdbpy_colorize_disasm (const std::string &content, gdbarch *gdbarch)
>
> \f
>
> +/* Implement gdb.format_address(ADDR,P_SPACE,ARCH). Provide access to
> + GDB's print_address function from Python. The returned address will
> + have the format '0x..... <symbol+offset>'. */
> +
> +static PyObject *
> +gdbpy_format_address (PyObject *self, PyObject *args, PyObject *kw)
> +{
> + static const char *keywords[] =
> + {
> + "address", "progspace", "architecture", nullptr
> + };
> + PyObject *addr_obj = nullptr, *pspace_obj = nullptr, *arch_obj = nullptr;
> + CORE_ADDR addr;
> + struct gdbarch *gdbarch = nullptr;
> + struct program_space *pspace = nullptr;
> +
> + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O|OO", keywords,
> + &addr_obj, &pspace_obj, &arch_obj))
> + return nullptr;
> +
> + if (get_addr_from_python (addr_obj, &addr) < 0)
> + return nullptr;
> +
> + /* If the user passed None for progspace or architecture, then we
> + consider this to mean "the default". Here we replace references to
> + None with nullptr, this means that in the following code we only have
> + to handle the nullptr case. These are only borrowed references, so
> + no decref is required here. */
> + if (pspace_obj == Py_None)
> + pspace_obj = nullptr;
> + if (arch_obj == Py_None)
> + arch_obj = nullptr;
> +
> + if (pspace_obj == nullptr && arch_obj == nullptr)
> + {
> + /* Grab both of these from the current inferior, and its associated
> + default architecture. */
> + pspace = current_inferior ()->pspace;
> + gdbarch = current_inferior ()->gdbarch;
> + }
> + else if (arch_obj == nullptr || pspace_obj == nullptr)
> + {
> + /* If the user has only given one of program space or architecture,
> + then don't use the default for the other. Sure we could use the
> + default, but it feels like there's too much scope of mistakes in
> + this case, so better to require the user to provide both
> + arguments. */
> + PyErr_SetString (PyExc_ValueError,
> + _("The architecture and progspace arguments must both be supplied"));
> + return nullptr;
> + }
> + else
> + {
> + /* The user provided an address, program space, and architecture.
> + Just check that these objects are valid. */
> + if (!gdbpy_is_progspace (pspace_obj))
> + {
> + PyErr_SetString (PyExc_TypeError,
> + _("The progspace argument is not a gdb.Progspace object"));
> + return nullptr;
> + }
> +
> + pspace = progspace_object_to_program_space (pspace_obj);
> + if (pspace == nullptr)
> + {
> + PyErr_SetString (PyExc_ValueError,
> + _("The progspace argument is not valid"));
> + return nullptr;
> + }
> +
> + if (!gdbpy_is_architecture (arch_obj))
> + {
> + PyErr_SetString (PyExc_TypeError,
> + _("The architecture argument is not a gdb.Architecture object"));
> + return nullptr;
> + }
> +
> + /* Architectures are never deleted once created, so gdbarch should
> + never come back as nullptr. */
> + gdbarch = arch_object_to_gdbarch (arch_obj);
> + gdb_assert (gdbarch != nullptr);
> + }
> +
> + /* By this point we should know the program space and architecture we are
> + going to use. */
> + gdb_assert (pspace != nullptr);
> + gdb_assert (gdbarch != nullptr);
> +
> + /* Unfortunately print_address relies on the current program space for
> + its symbol lookup. Temporarily switch now. */
> + scoped_restore_current_program_space restore_progspace;
> + set_current_program_space (pspace);
> +
> + /* Format the address, and return it as a string. */
> + string_file buf;
> + print_address (gdbarch, addr, &buf);
> + return PyString_FromString (buf.c_str ());
> +}
> +
> +\f
> +
> /* Printing. */
>
> /* A python function to write a single string using gdb's filtered
> @@ -2442,6 +2543,13 @@ Return a list of all the architecture names GDB understands." },
> "connections () -> List.\n\
> Return a list of gdb.TargetConnection objects." },
>
> + { "format_address", (PyCFunction) gdbpy_format_address,
> + METH_VARARGS | METH_KEYWORDS,
> + "format_address (ADDRESS, PROG_SPACE, ARCH) -> String.\n\
> +Format ADDRESS, an address within PROG_SPACE, a gdb.Progspace, using\n\
> +ARCH, a gdb.Architecture to determine the address size. The format of\n\
> +the returned string is 'ADDRESS <SYMBOL+OFFSET>' without the quotes." },
> +
> {NULL, NULL, 0, NULL}
> };
>
> diff --git a/gdb/testsuite/gdb.python/py-format-address.c b/gdb/testsuite/gdb.python/py-format-address.c
> new file mode 100644
> index 00000000000..6493fc4d579
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/py-format-address.c
> @@ -0,0 +1,32 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2022 Free Software Foundation, Inc.
> +
> + 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 <http://www.gnu.org/licenses/>. */
> +
> +/* This test is compiled multiple times with FUNCTION_NAME defined to
> + different strings, this means we should (hopefully) get the same code
> + layout in memory, but with different strings for the function name. */
> +
> +int
> +FUNCTION_NAME (void)
> +{
> + return 0;
> +}
> +
> +int
> +main (void)
> +{
> + return FUNCTION_NAME ();
> +}
> diff --git a/gdb/testsuite/gdb.python/py-format-address.exp b/gdb/testsuite/gdb.python/py-format-address.exp
> new file mode 100644
> index 00000000000..5c808299d34
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/py-format-address.exp
> @@ -0,0 +1,177 @@
> +# Copyright 2022 Free Software Foundation, Inc.
> +
> +# 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 <http://www.gnu.org/licenses/>.
> +
> +load_lib gdb-python.exp
> +standard_testfile
> +
> +foreach func_name { foo bar } {
> + if {[build_executable "build binary with ${func_name} function" \
> + "$testfile-${func_name}" $srcfile \
> + [list debug \
> + additional_flags=-DFUNCTION_NAME=${func_name}]] == -1} {
> + return -1
> + }
> +}
> +
> +set binary_foo [standard_output_file "${testfile}-foo"]
> +set binary_bar [standard_output_file "${testfile}-bar"]
> +
> +clean_restart $binary_foo
> +
> +# Skip all tests if Python scripting is not enabled.
> +if { [skip_python_tests] } { continue }
> +
> +if ![runto_main] {
> + return -1
> +}
> +
> +# Check the gdb.format_address method when using the default values
> +# for the program space and architecture (these will be selected based
> +# on the current inferior).
> +set main_addr [get_hexadecimal_valueof "&main" "UNKNOWN"]
> +set next_addr [format 0x%x [expr $main_addr + 1]]
> +
> +foreach_with_prefix symbol_filename { on off } {
> + gdb_test_no_output "set print symbol-filename ${symbol_filename}"
> +
> + if { $symbol_filename == "on" } {
> + set filename_pattern " at \[^\r\n\]+/${srcfile}:$decimal"
> + } else {
> + set filename_pattern ""
> + }
> +
> + gdb_test "python print(\"Got: \" + gdb.format_address($main_addr))" \
> + "Got: $main_addr <main${filename_pattern}>" \
> + "gdb.format_address, result should have no offset"
> +
> + gdb_test "python print(\"Got: \" + gdb.format_address($next_addr))" \
> + "Got: $next_addr <main\\+1${filename_pattern}>" \
> + "gdb.format_address, result should have an offset"
> +}
> +
> +if {![is_address_zero_readable]} {
> + gdb_test "python print(\"Got: \" + gdb.format_address(0))" \
> + "Got: 0x0" \
> + "gdb.format_address for address 0"
> +}
> +
> +# Now check that gdb.format_address will accept the program space and
> +# architecture arguments correctly.
> +gdb_test_no_output "python inf = gdb.selected_inferior()"
> +
> +# First, pass both arguments, this should be fine.
> +gdb_test "python print(\"Got: \" + gdb.format_address($main_addr, inf.progspace, inf.architecture()))" \
> + "Got: $main_addr <main>" \
> + "gdb.format_address passing program space and architecture"
> +
> +# Now pass the program space and architecture as None.
> +# First, pass both arguments, this should be fine.
> +gdb_test "python print(\"Got: \" + gdb.format_address($main_addr, None, None))" \
> + "Got: $main_addr <main>" \
> + "gdb.format_address passing program space and architecture as None"
> +
> +# Now forget the architecture, this should fail.
> +gdb_test "python print(\"Got: \" + gdb.format_address($main_addr, inf.progspace))" \
> + [multi_line \
> + "ValueError: The architecture and progspace arguments must both be supplied" \
> + "Error while executing Python code\\."] \
> + "gdb.format_address passing program space only"
> +
> +gdb_test "python print(\"Got: \" + gdb.format_address($main_addr, inf.progspace, None))" \
> + [multi_line \
> + "ValueError: The architecture and progspace arguments must both be supplied" \
> + "Error while executing Python code\\."] \
> + "gdb.format_address passing real program space, but architecture is None"
> +
> +# Now skip the program space argument.
> +gdb_test "python print(\"Got: \" + gdb.format_address($main_addr, architecture=inf.architecture()))" \
> + [multi_line \
> + "ValueError: The architecture and progspace arguments must both be supplied" \
> + "Error while executing Python code\\."] \
> + "gdb.format_address passing architecture only"
> +
> +gdb_test "python print(\"Got: \" + gdb.format_address($main_addr, None, inf.architecture()))" \
> + [multi_line \
> + "ValueError: The architecture and progspace arguments must both be supplied" \
> + "Error while executing Python code\\."] \
> + "gdb.format_address passing real architecture, but progspace is None"
> +
> +# Now, before we add a second inferior, lets just check we can format
> +# the address of 'foo' correctly.
> +set foo_addr [get_hexadecimal_valueof "&foo" "UNKNOWN"]
> +
> +gdb_test "python print(\"Got: \" + gdb.format_address($foo_addr, inf.progspace, inf.architecture()))" \
> + "Got: $foo_addr <foo>" \
> + "gdb.format_address for foo, with just one inferior"
> +
> +# Now lets add a second inferior, using a slightly different
> +# executable, select that inferior, and capture a reference to the
> +# inferior in a Python object.
> +gdb_test "add-inferior -exec ${binary_bar}" ".*" \
> + "add a second inferior running the bar executable"
> +gdb_test "inferior 2" ".*"
> +gdb_test_no_output "python inf2 = gdb.selected_inferior()"
> +
> +# Now we can test formatting an address from inferior 1.
> +gdb_test "python print(\"Got: \" + gdb.format_address($foo_addr, inf.progspace, inf.architecture()))" \
> + "Got: $foo_addr <foo>" \
> + "gdb.format_address for foo, while inferior 2 is selected"
> +
> +# Grab the address of 'bar'. Hopefully this will be the same address
> +# as 'foo', but if not, that's not the end of the world, the test just
> +# wont be quite as tough.
> +set bar_addr [get_hexadecimal_valueof "&bar" "UNKNOWN"]
> +
> +# Now format the address of bar using the default inferior and
> +# architecture, this should display the 'bar' symbol rather than
> +# 'foo'.
> +gdb_test "python print(\"Got: \" + gdb.format_address($bar_addr))" \
> + "Got: $foo_addr <bar>" \
> + "gdb.format_address for bar, while inferior 2 is selected"
> +
> +# And again, but this time, specificy the program space and
> +# architecture.
> +gdb_test "python print(\"Got: \" + gdb.format_address($bar_addr, inf2.progspace, inf2.architecture()))" \
> + "Got: $foo_addr <bar>" \
> + "gdb.format_address for bar, while inferior 2 is selected, pass progspace and architecture"
> +
> +# Reselect inferior 1, and then format an address from inferior 2.
> +gdb_test "inferior 1" ".*"
> +gdb_test "python print(\"Got: \" + gdb.format_address($bar_addr, inf2.progspace, inf2.architecture()))" \
> + "Got: $foo_addr <bar>" \
> + "gdb.format_address for bar, while inferior 1 is selected, pass progspace and architecture"
> +
> +# Try pasing incorrect object types for program space and architecture.
> +gdb_test "python print(\"Got: \" + gdb.format_address($bar_addr, inf2.progspace, inf2.progspace))" \
> + [multi_line \
> + "TypeError: The architecture argument is not a gdb.Architecture object" \
> + "Error while executing Python code\\."] \
> + "gdb.format_address pass wrong object type for architecture"
> +
> +gdb_test "python print(\"Got: \" + gdb.format_address($bar_addr, inf2.architecture(), inf2.architecture()))" \
> + [multi_line \
> + "TypeError: The progspace argument is not a gdb.Progspace object" \
> + "Error while executing Python code\\."] \
> + "gdb.format_address pass wrong object type for progspace"
> +
> +# Now invalidate inferior 2's program space, and try using that.
> +gdb_test "python pspace = inf2.progspace"
> +gdb_test "python arch = inf2.architecture()"
> +gdb_test "remove-inferior 2"
> +gdb_test "python print(\"Got: \" + gdb.format_address($bar_addr, pspace, arch))" \
> + [multi_line \
> + "ValueError: The progspace argument is not valid" \
> + "Error while executing Python code\\."] \
> + "gdb.format_address called with an invalid program space"
> --
> 2.25.4
next prev parent reply other threads:[~2022-03-21 17:53 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-11 16:17 [PATCH] gdb/python: add gdb.Architecture.format_address Andrew Burgess
2022-02-11 18:54 ` Eli Zaretskii
2022-02-21 17:27 ` Andrew Burgess
2022-02-21 18:02 ` Eli Zaretskii
2022-02-22 13:56 ` Andrew Burgess
2022-02-22 14:48 ` Eli Zaretskii
2022-02-23 14:20 ` Andrew Burgess
2022-03-03 16:49 ` Andrew Burgess
2022-03-03 18:35 ` Craig Blackmore
2022-03-04 10:51 ` Andrew Burgess
2022-03-04 10:50 ` [PATCHv2] " Andrew Burgess
2022-03-04 15:22 ` Simon Marchi
2022-03-07 12:33 ` [PATCHv3] gdb/python: add gdb.format_address function Andrew Burgess
2022-03-21 17:53 ` Andrew Burgess [this message]
2022-03-21 18:23 ` Simon Marchi
2022-03-22 13:19 ` Andrew Burgess
2022-03-23 12:14 ` Simon Marchi
2022-03-23 15:30 ` Andrew Burgess
2022-03-28 21:59 ` Simon Marchi
2022-03-29 13:38 ` Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87v8w7ry42.fsf@redhat.com \
--to=aburgess@redhat.com \
--cc=andrew.burgess@embecosm.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).