proc: workaround for macOS section name truncation (#3799)

Go 1.23 and earlier does not take into account that Mach-O section
names are limited to 16 characters, which causes DWARF sections with
long names to be truncated and become unreadable.

Fixes #3797
This commit is contained in:
Alessandro Arzilli 2024-09-03 19:39:27 +02:00 committed by GitHub
parent 2abf517c21
commit 162959baee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1971,6 +1971,7 @@ func loadBinaryInfoMacho(bi *BinaryInfo, image *Image, path string, entryPoint u
return &ErrUnsupportedArch{os: "darwin", cpuArch: exe.Cpu} return &ErrUnsupportedArch{os: "darwin", cpuArch: exe.Cpu}
} }
var dwerr error var dwerr error
macOSShortSectionNamesWorkaround(exe)
image.dwarf, dwerr = exe.DWARF() image.dwarf, dwerr = exe.DWARF()
if dwerr != nil { if dwerr != nil {
if len(bi.Images) <= 1 { if len(bi.Images) <= 1 {
@ -2133,6 +2134,38 @@ func (bi *BinaryInfo) macOSDebugFrameBugWorkaround() {
} }
} }
// macOSShortSectionNamesWorkaround works around a bug in Go 1.23 (and
// earlier).
// Section names in Macho-O executables are limited to 16 characters, which
// means that some DWARF sections with long names will be truncated. Go 1.23
// and prior do not take into account this making the DWARF info sometimes
// unreadable.
// This bug only manifests on macOS 15 because the C toolchain of prior
// versions of the operating system did not emit problematic DWARF sections.
// See also https://github.com/go-delve/delve/issues/3797
func macOSShortSectionNamesWorkaround(exe *macho.File) {
for _, sec := range exe.Sections {
if sec == nil {
continue
}
for _, longname := range []string{
"__debug_str_offsets",
"__zdebug_line_str",
"__zdebug_loclists",
"__zdebug_pubnames",
"__zdebug_pubtypes",
"__zdebug_rnglists",
"__zdebug_str_offsets",
} {
if sec.Name == longname[:16] {
logflags.DebuggerLogger().Debugf("expanding section name %q to %q", sec.Name, longname)
sec.Name = longname
break
}
}
}
}
// GO RUNTIME INFO //////////////////////////////////////////////////////////// // GO RUNTIME INFO ////////////////////////////////////////////////////////////
// loadBinaryInfoGoRuntimeElf loads information from the Go runtime sections // loadBinaryInfoGoRuntimeElf loads information from the Go runtime sections