Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <aburgess@redhat.com>
Subject: [PATCHv2 2/4] gdb/python: fix FinishBreakpoint.return_value for tail call functions
Date: Thu,  5 Mar 2026 13:37:16 +0000	[thread overview]
Message-ID: <c5523f40e54bcedc92f4d50249da62360f0961f6.1772717770.git.aburgess@redhat.com> (raw)
In-Reply-To: <cover.1772717769.git.aburgess@redhat.com>

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.
---
 gdb/python/py-finishbreakpoint.c                          | 6 +++---
 .../gdb.python/py-finish-breakpoint-tailcall.exp          | 8 +++++++-
 gdb/testsuite/gdb.python/py-finish-breakpoint-tailcall.py | 1 +
 3 files changed, 11 insertions(+), 4 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 =
diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint-tailcall.exp b/gdb/testsuite/gdb.python/py-finish-breakpoint-tailcall.exp
index e5b5ebc5183..2ae61f389ef 100644
--- a/gdb/testsuite/gdb.python/py-finish-breakpoint-tailcall.exp
+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint-tailcall.exp
@@ -66,11 +66,16 @@ proc run_test {} {
     set saw_stopped_message false
     set saw_breakpoint_line false
     set saw_source_line false
+    set saw_return_value false
     gdb_test_multiple "continue" "" {
 	-re "^Stopped at MyFinishBreakpoint\r\n" {
 	    set saw_stopped_message true
 	    exp_continue
 	}
+	-re "^Return value is 43\r\n" {
+	    set saw_return_value true
+	    exp_continue
+	}
 	-re "^Breakpoint $::decimal, main \\(\\) at \[^\r\n\]+/$::srcfile:$lineno\r\n" {
 	    set saw_breakpoint_line true
 	    exp_continue
@@ -82,7 +87,8 @@ proc run_test {} {
 	-re "^$::gdb_prompt $" {
 	    gdb_assert { $saw_stopped_message \
 			     && $saw_breakpoint_line \
-			     && $saw_source_line } $gdb_test_name
+			     && $saw_source_line \
+			     && $saw_return_value } $gdb_test_name
 	}
 	-re "^\[^\r\n\]*\r\n" {
 	    exp_continue
diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint-tailcall.py b/gdb/testsuite/gdb.python/py-finish-breakpoint-tailcall.py
index bd10109a3dc..e493dfa4017 100644
--- a/gdb/testsuite/gdb.python/py-finish-breakpoint-tailcall.py
+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint-tailcall.py
@@ -20,6 +20,7 @@ import gdb
 class MyFinishBreakpoint(gdb.FinishBreakpoint):
     def stop(self):
         print("Stopped at MyFinishBreakpoint")
+        print("Return value is {}".format(self.return_value))
         return True
 
 
-- 
2.25.4


  parent reply	other threads:[~2026-03-05 13:37 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-24 11:29 [PATCH 0/4] Fixes for tail call, until, and FinishBreakpoints Andrew Burgess
2026-01-24 11:29 ` [PATCH 1/4] gdb: fix frame_unwind_caller_WHAT functions for inline and tail calls Andrew Burgess
2026-01-27 16:37   ` Andrew Burgess
2026-01-24 11:29 ` [PATCH 2/4] gdb/python: fix FinishBreakpoint.return_value for tail call functions Andrew Burgess
2026-01-24 11:29 ` [PATCH 3/4] gdb/python: don't allow FinishBreakpoints for inline frames Andrew Burgess
2026-01-24 12:23   ` Eli Zaretskii
2026-01-24 11:29 ` [PATCH 4/4] gdb/python: fix gdb.FinishBreakpoint returning to a tail call frame Andrew Burgess
2026-03-05 13:37 ` [PATCHv2 0/4] Fixes for tail call, until, and FinishBreakpoints Andrew Burgess
2026-03-05 13:37   ` [PATCHv2 1/4] gdb: fix frame_unwind_caller_WHAT functions for inline and tail calls Andrew Burgess
2026-03-05 13:37   ` Andrew Burgess [this message]
2026-03-05 13:37   ` [PATCHv2 3/4] gdb/python: don't allow FinishBreakpoints for inline frames Andrew Burgess
2026-03-05 13:37   ` [PATCHv2 4/4] gdb/python: fix gdb.FinishBreakpoint returning to a tail call frame Andrew Burgess
2026-03-05 15:59   ` [PATCHv2 0/4] Fixes for tail call, until, and FinishBreakpoints Tom Tromey
2026-03-05 17:49     ` 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=c5523f40e54bcedc92f4d50249da62360f0961f6.1772717770.git.aburgess@redhat.com \
    --to=aburgess@redhat.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