]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
Fix dwarf2 "assertion failed" on bra without skip dwarf expression op
authorJaro Fietz <jaro.fietz@gmx.de>
Fri, 14 Nov 2025 20:55:08 +0000 (21:55 +0100)
committerTom Tromey <tromey@adacore.com>
Thu, 20 Nov 2025 16:06:09 +0000 (09:06 -0700)
commitcc27559a20f4238a0f3fb31c02dbd2c9fecaed65
tree2fb5f1cf533d2f0c99a0f32fb66dd3c2f76e536b
parente086501cca047f6dd35bc24e7af9960113b9faf3
Fix dwarf2 "assertion failed" on bra without skip dwarf expression op

When interpreting dwarf expressions, the function
dwarf2_get_symbol_read_needs walks over all instructions via
the call graph by using a to-visit and a visited list.
Upon reaching a bra operation, it pushes both the next op and the
branch target into the to-visit list.
If the branch-target can be reached linearly from the next op,
the branch-target will be visited twice.

At the top of the visit-loop, there is an assertion that a visited
instruction must never be visited again.
This assertion fails in the above case.

For example a DIE with DW_AT_location: 30 31 28 0 0 9f
(DW_OP_lit0; DW_OP_lit1; DW_OP_bra: 0; DW_OP_stack_value)
will result in
.././binutils-gdb/gdb/dwarf2/loc.c:1905: internal-error: dwarf2_get_symbol_read_needs: Assertion `visited_ops.find (op_ptr) == visited_ops.end ()' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.

Adding a skip operation which makes the branch-target not linearly
accessible from the next op, makes the example work. For example a
DIE with DW_AT_location: 32 31 28 3 0 2f 1 0 96 9f (DW_OP_lit2;
DW_OP_lit1; DW_OP_bra: 3; DW_OP_skip: 1; DW_OP_nop; DW_OP_stack_value)
produces the correct result $1 = 2.

This patch replaces the failing assertion with a continue to properly
skip an already visited dwarf expression op.
This makes the first example work correctly and result in $1 = 0.

Running the testsuite resulted in different results upon every run
(arch-linux 6.17.7-arch1-1 x86_64).
Comparing the results of 3 runs of the unmodified code with three
runs containing the fix does not yield a significant difference:

unmodified version: # of expected passes 126821, 126813, 126838
fix version: # of expected passes 126866, 126801, 126817

Approved-By: Tom Tromey <tom@tromey.com>
gdb/dwarf2/loc.c