Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] gdb/dwarf: fix internal error in dwarf2_fetch_cfa_info for FDEs without a CFA rule
@ 2026-04-23 17:37 Simon Marchi
  2026-04-24  2:18 ` Kevin Buettner
  0 siblings, 1 reply; 3+ messages in thread
From: Simon Marchi @ 2026-04-23 17:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Commit a910478f65a5 ("gdb/dwarf: fix internal error when FDEs do not
describe the CFA") fixed the switch on cfa_how in dwarf2_frame_cache,
but there is a very similar switch in dwarf2_fetch_cfa_info that has
the same issue.  If the unwind info does not set a rule for the CFA,
fs.regs.cfa_how is left as CFA_UNSET and we hit the default case,
triggering an internal error.

dwarf2_fetch_cfa_info is called from two places, both while compiling
a DWARF expression that contains DW_OP_call_frame_cfa:

 - dwarf2_compile_expr_to_ax, when compiling to agent-expression
   bytecode

 - do_compile_dwarf_expr_to_c, when compiling to C source (used by
   the "compile" commands).

Unlike dwarf2_frame_cache, where we can degrade gracefully by setting
undefined_retaddr, the callers of dwarf2_fetch_cfa_info need a concrete
CFA to generate code, so we can't continue.  Throw an error with the
same message used a few lines above, when the FDE itself cannot be
found.

Extend the debug-frame-no-cfa.exp test to reproduce this case: add a
compile unit describing the "main" function and with a DW_AT_frame_base
that uses DW_OP_call_frame_cfa and a local variable "x" that uses
DW_OP_fbreg (the evaluation of which requires the CFA).  Then, try to
translate the location of "x" to agent-expression bytecode with "maint"
agent.  This hits the internal error without the corresponding fix.

Change-Id: I82349e3d9259c8f943eabee5c2fce360876feee8
---
 gdb/dwarf2/frame.c                            |  3 ++
 .../gdb.dwarf2/debug-frame-no-cfa.exp         | 36 +++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index 2301d9146373..70895e90696d 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -793,6 +793,9 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
   /* Calculate the CFA.  */
   switch (fs.regs.cfa_how)
     {
+    case CFA_UNSET:
+      error (_("Could not compute CFA; needed to translate this expression"));
+
     case CFA_REG_OFFSET:
       {
 	int regnum = dwarf_reg_to_regnum_or_error (gdbarch, fs.regs.cfa_reg);
diff --git a/gdb/testsuite/gdb.dwarf2/debug-frame-no-cfa.exp b/gdb/testsuite/gdb.dwarf2/debug-frame-no-cfa.exp
index 8442b5c3ddbb..3f7d77cf0745 100644
--- a/gdb/testsuite/gdb.dwarf2/debug-frame-no-cfa.exp
+++ b/gdb/testsuite/gdb.dwarf2/debug-frame-no-cfa.exp
@@ -26,6 +26,36 @@ set asm_file [standard_output_file $srcfile2]
 Dwarf::assemble $asm_file {
     get_func_info main
 
+    cu { version 5 } {
+	DW_TAG_compile_unit {
+	    DW_AT_name debug-frame-no-cfa.c
+	    DW_AT_comp_dir /tmp
+	} {
+	    declare_labels int_type_label
+
+	    int_type_label: DW_TAG_base_type {
+		DW_AT_name "int"
+		DW_AT_encoding @DW_ATE_signed
+		DW_AT_byte_size 4 DW_FORM_sdata
+	    }
+
+	    DW_TAG_subprogram {
+		MACRO_AT_func { main }
+		DW_AT_frame_base {
+		    DW_OP_call_frame_cfa
+		} SPECIAL_expr
+	    } {
+		DW_TAG_variable {
+		    DW_AT_name x
+		    DW_AT_type :$int_type_label
+		    DW_AT_location {
+			DW_OP_fbreg 0
+		    } SPECIAL_expr
+		}
+	    }
+	}
+    }
+
     frame {
 	declare_labels cie_label
 
@@ -52,3 +82,9 @@ if { ![runto_main] } {
 # Make sure to match a single line, so that the test fails if an error
 # about stack unwind is printed after frame 0.
 gdb_test "backtrace" "^#0 \[^\r\n\]* main \[^\r\n\]*"
+
+# Translating the location of "x" to an agent expression requires
+# evaluating its frame base, which uses DW_OP_call_frame_cfa.  This would
+# cause an internal error in dwarf2_fetch_cfa_info.
+gdb_test "maint agent x" \
+    "Could not compute CFA; needed to translate this expression"

base-commit: 8dc535c59fdbcf99e28703425e5c1c711e63a1f1
-- 
2.54.0


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

* Re: [PATCH] gdb/dwarf: fix internal error in dwarf2_fetch_cfa_info for FDEs without a CFA rule
  2026-04-23 17:37 [PATCH] gdb/dwarf: fix internal error in dwarf2_fetch_cfa_info for FDEs without a CFA rule Simon Marchi
@ 2026-04-24  2:18 ` Kevin Buettner
  2026-04-24  2:29   ` Simon Marchi
  0 siblings, 1 reply; 3+ messages in thread
From: Kevin Buettner @ 2026-04-24  2:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

On Thu, 23 Apr 2026 13:37:06 -0400
Simon Marchi <simon.marchi@efficios.com> wrote:

> Commit a910478f65a5 ("gdb/dwarf: fix internal error when FDEs do not
> describe the CFA") fixed the switch on cfa_how in dwarf2_frame_cache,
> but there is a very similar switch in dwarf2_fetch_cfa_info that has
> the same issue.  If the unwind info does not set a rule for the CFA,
> fs.regs.cfa_how is left as CFA_UNSET and we hit the default case,
> triggering an internal error.
> 
> dwarf2_fetch_cfa_info is called from two places, both while compiling
> a DWARF expression that contains DW_OP_call_frame_cfa:
> 
>  - dwarf2_compile_expr_to_ax, when compiling to agent-expression
>    bytecode
> 
>  - do_compile_dwarf_expr_to_c, when compiling to C source (used by
>    the "compile" commands).
> 
> Unlike dwarf2_frame_cache, where we can degrade gracefully by setting
> undefined_retaddr, the callers of dwarf2_fetch_cfa_info need a concrete
> CFA to generate code, so we can't continue.  Throw an error with the
> same message used a few lines above, when the FDE itself cannot be
> found.
> 
> Extend the debug-frame-no-cfa.exp test to reproduce this case: add a
> compile unit describing the "main" function and with a DW_AT_frame_base
> that uses DW_OP_call_frame_cfa and a local variable "x" that uses
> DW_OP_fbreg (the evaluation of which requires the CFA).  Then, try to
> translate the location of "x" to agent-expression bytecode with "maint"
> agent.  This hits the internal error without the corresponding fix.

LGTM.

Approved-by: Kevin Buettner <kevinb@redhat.com>


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

* Re: [PATCH] gdb/dwarf: fix internal error in dwarf2_fetch_cfa_info for FDEs without a CFA rule
  2026-04-24  2:18 ` Kevin Buettner
@ 2026-04-24  2:29   ` Simon Marchi
  0 siblings, 0 replies; 3+ messages in thread
From: Simon Marchi @ 2026-04-24  2:29 UTC (permalink / raw)
  To: Kevin Buettner, gdb-patches; +Cc: Simon Marchi



On 2026-04-23 22:18, Kevin Buettner wrote:
> On Thu, 23 Apr 2026 13:37:06 -0400
> Simon Marchi <simon.marchi@efficios.com> wrote:
> 
>> Commit a910478f65a5 ("gdb/dwarf: fix internal error when FDEs do not
>> describe the CFA") fixed the switch on cfa_how in dwarf2_frame_cache,
>> but there is a very similar switch in dwarf2_fetch_cfa_info that has
>> the same issue.  If the unwind info does not set a rule for the CFA,
>> fs.regs.cfa_how is left as CFA_UNSET and we hit the default case,
>> triggering an internal error.
>>
>> dwarf2_fetch_cfa_info is called from two places, both while compiling
>> a DWARF expression that contains DW_OP_call_frame_cfa:
>>
>>  - dwarf2_compile_expr_to_ax, when compiling to agent-expression
>>    bytecode
>>
>>  - do_compile_dwarf_expr_to_c, when compiling to C source (used by
>>    the "compile" commands).
>>
>> Unlike dwarf2_frame_cache, where we can degrade gracefully by setting
>> undefined_retaddr, the callers of dwarf2_fetch_cfa_info need a concrete
>> CFA to generate code, so we can't continue.  Throw an error with the
>> same message used a few lines above, when the FDE itself cannot be
>> found.
>>
>> Extend the debug-frame-no-cfa.exp test to reproduce this case: add a
>> compile unit describing the "main" function and with a DW_AT_frame_base
>> that uses DW_OP_call_frame_cfa and a local variable "x" that uses
>> DW_OP_fbreg (the evaluation of which requires the CFA).  Then, try to
>> translate the location of "x" to agent-expression bytecode with "maint"
>> agent.  This hits the internal error without the corresponding fix.
> 
> LGTM.
> 
> Approved-by: Kevin Buettner <kevinb@redhat.com>
> 

Thanks, pushed.

Simon

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

end of thread, other threads:[~2026-04-24  2:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-23 17:37 [PATCH] gdb/dwarf: fix internal error in dwarf2_fetch_cfa_info for FDEs without a CFA rule Simon Marchi
2026-04-24  2:18 ` Kevin Buettner
2026-04-24  2:29   ` Simon Marchi

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