Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH 0/1] gdb: discard saved state on error in recursive infcall
@ 2026-06-19 14:11 Stephan Rohr
  2026-06-19 14:12 ` [PATCH 1/1] " Stephan Rohr
  2026-07-06  7:37 ` [PATCH 0/1] " Rohr, Stephan
  0 siblings, 2 replies; 3+ messages in thread
From: Stephan Rohr @ 2026-06-19 14:11 UTC (permalink / raw)
  To: gdb-patches

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

Hi all,

I came across an issue when we hit a breakpoint in the copy constructor
during an infcall.  GDB runs a nested 'call_function_by_hand (copy_ctor,
...)' that creates the dummy frame.  If we hit a breakpoint inside the
ctor, that call raises an error.  The parent
'call_function_by_hand_dummy' restores the caller's registers.

This works fine until the frame cache is reinitialized, e.g., when
switching inferiors.  In that case, the unwinder cannot reach the dummy
frame anymore and the backtrace command doesn't show the correct frames.

I fixed this by not restoring the caller's state and the inferior status
on errors inside the nested ctor call.  I extended the
'gdb.cp/pass-by-ref-2.exp' testcase to ensure GDB is able to finish the
abandoned infcall.

Regression tested on Ubuntu 24 with the native target.

I appreciate your feedback.

Thanks
Stephan

Rohr, Stephan (1):
  gdb: discard saved state on error in recursive infcall

 gdb/infcall.c                          | 23 +++++++++++++++++++++--
 gdb/testsuite/gdb.cp/pass-by-ref-2.exp | 22 ++++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

-- 
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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/1] gdb: discard saved state on error in recursive infcall
  2026-06-19 14:11 [PATCH 0/1] gdb: discard saved state on error in recursive infcall Stephan Rohr
@ 2026-06-19 14:12 ` Stephan Rohr
  2026-07-06  7:37 ` [PATCH 0/1] " Rohr, Stephan
  1 sibling, 0 replies; 3+ messages in thread
From: Stephan Rohr @ 2026-06-19 14:12 UTC (permalink / raw)
  To: gdb-patches

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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: [PATCH 0/1] gdb: discard saved state on error in recursive infcall
  2026-06-19 14:11 [PATCH 0/1] gdb: discard saved state on error in recursive infcall Stephan Rohr
  2026-06-19 14:12 ` [PATCH 1/1] " Stephan Rohr
@ 2026-07-06  7:37 ` Rohr, Stephan
  1 sibling, 0 replies; 3+ messages in thread
From: Rohr, Stephan @ 2026-07-06  7:37 UTC (permalink / raw)
  To: Rohr, Stephan, gdb-patches

Kindly pinging.

Thanks
Stephan

> -----Original Message-----
> From: Stephan Rohr <stephan.rohr@intel.com>
> Sent: Friday, 19 June 2026 16:12
> To: gdb-patches@sourceware.org
> Subject: [PATCH 0/1] gdb: discard saved state on error in recursive infcall
> 
> From: "Rohr, Stephan" <stephan.rohr@intel.com>
> 
> Hi all,
> 
> I came across an issue when we hit a breakpoint in the copy constructor
> during an infcall.  GDB runs a nested 'call_function_by_hand (copy_ctor,
> ...)' that creates the dummy frame.  If we hit a breakpoint inside the
> ctor, that call raises an error.  The parent
> 'call_function_by_hand_dummy' restores the caller's registers.
> 
> This works fine until the frame cache is reinitialized, e.g., when
> switching inferiors.  In that case, the unwinder cannot reach the dummy
> frame anymore and the backtrace command doesn't show the correct frames.
> 
> I fixed this by not restoring the caller's state and the inferior status
> on errors inside the nested ctor call.  I extended the
> 'gdb.cp/pass-by-ref-2.exp' testcase to ensure GDB is able to finish the
> abandoned infcall.
> 
> Regression tested on Ubuntu 24 with the native target.
> 
> I appreciate your feedback.
> 
> Thanks
> Stephan
> 
> Rohr, Stephan (1):
>   gdb: discard saved state on error in recursive infcall
> 
>  gdb/infcall.c                          | 23 +++++++++++++++++++++--
>  gdb/testsuite/gdb.cp/pass-by-ref-2.exp | 22 ++++++++++++++++++++++
>  2 files changed, 43 insertions(+), 2 deletions(-)
> 
> --
> 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

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-06  7:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-19 14:11 [PATCH 0/1] gdb: discard saved state on error in recursive infcall Stephan Rohr
2026-06-19 14:12 ` [PATCH 1/1] " Stephan Rohr
2026-07-06  7:37 ` [PATCH 0/1] " Rohr, Stephan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox