From: Simon Marchi <simon.marchi@efficios.com>
To: gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@efficios.com>
Subject: [PATCH] gdb/dwarf: fix internal error in dwarf2_fetch_cfa_info for FDEs without a CFA rule
Date: Thu, 23 Apr 2026 13:37:06 -0400 [thread overview]
Message-ID: <20260423173711.804174-1-simon.marchi@efficios.com> (raw)
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
next reply other threads:[~2026-04-23 17:37 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-23 17:37 Simon Marchi [this message]
2026-04-24 2:18 ` Kevin Buettner
2026-04-24 2:29 ` Simon Marchi
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=20260423173711.804174-1-simon.marchi@efficios.com \
--to=simon.marchi@efficios.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