Skip to content

Commit 1982303

Browse files
committed
merge revision(s) 954b7ac: [Backport #19789]
addr2line.c: fix `DW_FORM_ref_addr` parsing for DWARF 2 (ruby#8146) addr2line.c: fix DW_FORM_ref_addr parsing for DWARF 2 This fixes a crash when retrieving backtrace info with YJIT enabled on macOS with Rust 1.71.0. Since Rust 1.71.0, the DWARF info generated by the Rust compiler uses DW_FORM_ref_addr instead of DW_FORM_ref4 for pointers to other DIEs. DW_FORM_ref_addr representation in DWARF 2 is different from DWARF 3+, so we need to handle it separately. This patch fixes the parsing of DW_FORM_ref_addr for DWARF 2, which is the default DWARF version Rustc uses on macOS. See the DWARF 2.0.0 spec, section 7.5.4 Attribute Encodings https://dwarfstd.org/doc/dwarf-2.0.0.pdf https://bugs.ruby-lang.org/issues/19789 --- addr2line.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-)
1 parent 1c76244 commit 1982303

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

addr2line.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,19 +1144,25 @@ resolve_strx(DebugInfoReader *reader, uint64_t idx)
11441144
return reader->obj->debug_str.ptr + off;
11451145
}
11461146

1147+
static void
1148+
debug_info_reader_read_addr_value(DebugInfoReader *reader, DebugInfoValue *v)
1149+
{
1150+
if (reader->address_size == 4) {
1151+
set_uint_value(v, read_uint32(&reader->p));
1152+
} else if (reader->address_size == 8) {
1153+
set_uint_value(v, read_uint64(&reader->p));
1154+
} else {
1155+
fprintf(stderr,"unknown address_size:%d", reader->address_size);
1156+
abort();
1157+
}
1158+
}
1159+
11471160
static void
11481161
debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v)
11491162
{
11501163
switch (form) {
11511164
case DW_FORM_addr:
1152-
if (reader->address_size == 4) {
1153-
set_uint_value(v, read_uint32(&reader->p));
1154-
} else if (reader->address_size == 8) {
1155-
set_uint_value(v, read_uint64(&reader->p));
1156-
} else {
1157-
fprintf(stderr,"unknown address_size:%d", reader->address_size);
1158-
abort();
1159-
}
1165+
debug_info_reader_read_addr_value(reader, v);
11601166
break;
11611167
case DW_FORM_block2:
11621168
v->size = read_uint16(&reader->p);
@@ -1208,13 +1214,19 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
12081214
set_uint_value(v, read_uleb128(reader));
12091215
break;
12101216
case DW_FORM_ref_addr:
1211-
if (reader->format == 4) {
1212-
set_uint_value(v, read_uint32(&reader->p));
1213-
} else if (reader->format == 8) {
1214-
set_uint_value(v, read_uint64(&reader->p));
1217+
if (reader->current_version <= 2) {
1218+
// DWARF Version 2 specifies that references have
1219+
// the same size as an address on the target system
1220+
debug_info_reader_read_addr_value(reader, v);
12151221
} else {
1216-
fprintf(stderr,"unknown format:%d", reader->format);
1217-
abort();
1222+
if (reader->format == 4) {
1223+
set_uint_value(v, read_uint32(&reader->p));
1224+
} else if (reader->format == 8) {
1225+
set_uint_value(v, read_uint64(&reader->p));
1226+
} else {
1227+
fprintf(stderr,"unknown format:%d", reader->format);
1228+
abort();
1229+
}
12181230
}
12191231
break;
12201232
case DW_FORM_ref1:

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
1212
#define RUBY_VERSION_TEENY 2
1313
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
14-
#define RUBY_PATCHLEVEL 107
14+
#define RUBY_PATCHLEVEL 108
1515

1616
#include "ruby/version.h"
1717
#include "ruby/internal/abi.h"

0 commit comments

Comments
 (0)