aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2026-01-23 09:57:24 +0000
committerAndrew Burgess <aburgess@redhat.com>2026-03-05 17:45:27 +0000
commitd0c1dcb58e8d88f2c4ede55573dac7f04c3cfd55 (patch)
treea9ae03e4e4fc32f45582f8caa5023c2619bb870e /gdb/python
parente6bdfed6f5d6d5338b552f8a07577a12d9b49279 (diff)
downloadbinutils-d0c1dcb58e8d88f2c4ede55573dac7f04c3cfd55.tar.gz
binutils-d0c1dcb58e8d88f2c4ede55573dac7f04c3cfd55.tar.bz2
binutils-d0c1dcb58e8d88f2c4ede55573dac7f04c3cfd55.zip
gdb/python: fix FinishBreakpoint.return_value for tail call functions
The FinishBreakpoint.return_value attribute will not be populated correctly for tail call functions. In bpfinishpy_init (python/py-finishbreakpoint.c) we use the function get_frame_pc_if_available to return an address, and then use this address to lookup a function symbol. The problem is that, for tail call functions, the address returned by get_frame_pc_if_available can be outside the bounds of the function, as a result GDB might find no function symbol at all, or might find the wrong function symbol, if the tail call function is immediately adjacent to the next function. Fix this by using get_frame_address_in_block_if_available instead. For tail call functions this will return an address within the bounds of the function, which means that GDB should find the correct function symbol, and from this the correct return type. I've extended the existing FinishBreakpoint with tail call test case to include printing the return value, this test fails without this patch, but now works. Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/py-finishbreakpoint.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c
index 3370bb02580..4af8ec6c75f 100644
--- a/gdb/python/py-finishbreakpoint.c
+++ b/gdb/python/py-finishbreakpoint.c
@@ -174,7 +174,6 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
struct frame_id frame_id;
PyObject *internal = NULL;
int internal_bp = 0;
- std::optional<CORE_ADDR> pc;
if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "|OO", keywords,
&frame_obj, &internal))
@@ -248,9 +247,10 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
try
{
- if ((pc = get_frame_pc_if_available (frame)))
+ CORE_ADDR pc;
+ if (get_frame_address_in_block_if_available (frame, &pc))
{
- struct symbol *function = find_symbol_for_pc (*pc);
+ struct symbol *function = find_symbol_for_pc (pc);
if (function != nullptr)
{
struct type *ret_type =