From: Tom de Vries Date: Wed, 10 Jun 2026 07:54:22 +0000 (+0200) Subject: [gdb/contrib] Fix KeyError in dwarf-to-dwarf-assembler.py X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=04e04460078274b4011b5cb892e162ff61083fcb;p=thirdparty%2Fbinutils-gdb.git [gdb/contrib] Fix KeyError in dwarf-to-dwarf-assembler.py Executable outputs/gdb.threads/stepi-over-clone/stepi-over-clone contains the following DWARF (using readelf -w): ... <31c5> DW_AT_const_value : 8 byte block: ff ff ff ff ff ff ff ff ... or more explicit using llvm-dwarfdump -v: ... DW_AT_const_value [DW_FORM_block1] \ (<0x08> ff ff ff ff ff ff ff ff ) ... Before commit 18ad8c1a54d ("Emit DWARF expressions from dwarf-to-dwarf-assembler.py"), the dwarf-to-dwarf-assembler.py script generated: ... DW_AT_const_value { MANUAL: Fill expr list } SPECIAL_expr ... for this. But since the commit, we run into a KeyError. The problem is that we're trying to interpret some random data as a DWARF expression. Fix this by special-casing DW_AT_const_value, and generating instead: ... DW_AT_const_value "\xff\xff\xff\xff\xff\xff\xff\xff" DW_FORM_block1 ... which mimics the style I found in gdb.dwarf2/info-locals-optimized-out.exp: ... DW_TAG_variable { DW_AT_name const_bytes DW_AT_type :$int_type_label DW_AT_const_value "\x01\x01\x01\x01" DW_FORM_block1 } ... Likewise for DW_AT_discr_list. Another case for which the KeyError triggers, is DWARF from outputs/gdb.ada/array_of_variant/p-minimal: ... <2><14a4>: Abbrev Number: 20 (DW_TAG_structure_type) <14a5> DW_AT_name : p__payload_t <14a9> DW_AT_byte_size : 18 byte block: \ fd 63 14 0 0 97 94 1 99 45 0 0 0 23 7 9 fc 1a \ (DW_OP_GNU_variable_value: <0x1463>; \ DW_OP_push_object_address; \ DW_OP_deref_size: 1; \ DW_OP_call4: <0x1421>; \ DW_OP_plus_uconst: 7; \ DW_OP_const1s: -4; DW_OP_and) ... because the pyelftools version that I'm using doesn't support DW_OP_GNU_variable_value yet (supported starting v0.33). Fix this by catching the KeyError, and falling back to the string case: ... DW_AT_byte_size \ "\xfd\x63\x14\x00\x00\x97\x94\x01\x99\x45\x00\x00\x00\x23\x07\x09\xfc\x1a" \ DW_FORM_exprloc # Failed to print op as DWARF expression: 0xfd ... --- diff --git a/gdb/contrib/dwarf-to-dwarf-assembler.py b/gdb/contrib/dwarf-to-dwarf-assembler.py index 314a9e9587b..fa32bc4bbab 100755 --- a/gdb/contrib/dwarf-to-dwarf-assembler.py +++ b/gdb/contrib/dwarf-to-dwarf-assembler.py @@ -226,9 +226,23 @@ class DWARFAttribute: elif self.name == "DW_AT_encoding" and isinstance(self.value, int): s += "@" + ATE_NAME[self.value] elif self.form in EXPR_ATTRIBUTE_FORMS: - # This returns a complete description that is already - # indented. - return self._format_expr_value(s, indent_count) + postfix = "" + if self.name not in ["DW_AT_const_value", "DW_AT_discr_list"]: + # Try to print as a DWARF expression. + try: + # This returns a complete description that is already + # indented. + return self._format_expr_value(s, indent_count) + except KeyError as e: + # Fall through to basic printing. + postfix = " # Failed to print op as DWARF expression: " + hex( + int(str(e)) + ) + # Print the data as a string in "\x01\x02\x03\x04" format. + result = "" + for op in self.value: + result += f"\\x{op:02x}" + return indent(s, indent_count) + '"' + result + '" ' + self.form + postfix else: s += self._format_value(offset_die_lookup)