Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Stephan Rohr <stephan.rohr@intel.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 1/1] gdb: discard saved state on error in recursive infcall
Date: Fri, 19 Jun 2026 14:12:00 +0000	[thread overview]
Message-ID: <20260619141200.97232-2-stephan.rohr@intel.com> (raw)
In-Reply-To: <20260619141200.97232-1-stephan.rohr@intel.com>

From: "Rohr, Stephan" <stephan.rohr@intel.com>

GDB invokes a ctor for all arguments not trivially copyable in an
inferior call.  The caller's registers and other state are restored,
even if an exception inside the callee is raised.  This hides the
correct frame from the user in certain scenarios, e.g., when switching
inferiors.  The extra frame-cache reinit re-reads the restored registers
such that 'backtrace' only shows the 'main' frame instead of the
breakpoint hit in the inferior call.

Discard the saved state on gdb_exception_error when invoking the ctor in
inferior calls.
---
 gdb/infcall.c                          | 23 +++++++++++++++++++++--
 gdb/testsuite/gdb.cp/pass-by-ref-2.exp | 22 ++++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/gdb/infcall.c b/gdb/infcall.c
index e6b24ff5310..e40724c6b83 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -1402,8 +1402,27 @@ call_function_by_hand_dummy (struct value *function,
 		     "constructor for the type '%s' could not be found "
 		     "(maybe inlined?)"), param_type->name ());
 
-	  call_function_by_hand (copy_ctor, default_return_type,
-				 gdb::make_array_view (cctor_args, 2));
+	  try
+	    {
+	      call_function_by_hand (copy_ctor, default_return_type,
+				     gdb::make_array_view (cctor_args, 2));
+	    }
+	  catch (const gdb_exception_error &)
+	    {
+	      /* We hit an error in the ctor.
+
+		 Discard inferior status, we're not at the same point
+		 we started at.  */
+	      discard_infcall_control_state (inf_status.release ());
+
+	      /* The nested call of the copy constructor may have set up a
+		 dummy frame before throwing the error.  Restoring the
+		 caller's registers would leave that dummy frame unreachable
+		 by the unwinder once the frame cache is invalidated.  */
+	      discard_infcall_suspend_state (caller_state.release ());
+
+	      throw;
+	    }
 	}
 
       /* If the argument has a destructor, remember it so that we
diff --git a/gdb/testsuite/gdb.cp/pass-by-ref-2.exp b/gdb/testsuite/gdb.cp/pass-by-ref-2.exp
index 3d704635901..42b67c1fba1 100644
--- a/gdb/testsuite/gdb.cp/pass-by-ref-2.exp
+++ b/gdb/testsuite/gdb.cp/pass-by-ref-2.exp
@@ -109,8 +109,30 @@ gdb_breakpoint $bp_location
 gdb_test "print cbvArrayContainerByRef (arrayContainerByRef)" \
     ".*The program being debugged stopped.*" \
     "call cbvArrayContainerByRef with BP"
+
+# Switching inferiors reinitializes the frame cache.
+gdb_test "add-inferior"
+gdb_test "inferior 2"
+gdb_test "inferior 1"
+
 gdb_test "backtrace" [multi_line \
     "#0  ByRef\:\:ByRef .* at .*$srcfile:$bp_location" \
     "#1  .* ArrayContainerByRef::ArrayContainerByRef .*" \
     "#2  <function called from gdb>" \
     "#3  main.*"]
+
+# Test GDB is able to finish the abandoned inferior call.
+
+delete_breakpoints
+
+gdb_test "finish" [multi_line \
+    "Run till exit from #0  ByRef\:\:ByRef .* at .*$srcfile:$bp_location" \
+    ".* in ArrayContainerByRef::ArrayContainerByRef .* at .*$srcfile:.*"] \
+    "finish frame #0"
+
+gdb_test "finish" [multi_line \
+    "Run till exit from #0  .* in ArrayContainerByRef::ArrayContainerByRef .* at .*$srcfile:.*" \
+    "main \\(\\) at .*$srcfile:.*"] \
+    "finish frame #1"
+
+gdb_continue_to_end
-- 
2.43.0

Intel Deutschland GmbH

Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


  reply	other threads:[~2026-06-19 14:13 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-19 14:11 [PATCH 0/1] " Stephan Rohr
2026-06-19 14:12 ` Stephan Rohr [this message]
2026-07-06  7:37 ` Rohr, Stephan

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=20260619141200.97232-2-stephan.rohr@intel.com \
    --to=stephan.rohr@intel.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