From 1d8636cd3da8cd02a154dd3415b42476c336225c Mon Sep 17 00:00:00 2001 From: Peter Sanford Date: Fri, 29 Jun 2018 15:02:53 -0700 Subject: [PATCH] Handle gdb core files better Core files created by gdb can have sections missing that would be present in OS created core files. We work around this by first reading PT_LOAD entries from the exe and then reading them from the core. Fixes #1121 --- pkg/proc/core/linux_amd64_core.go | 34 +++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/pkg/proc/core/linux_amd64_core.go b/pkg/proc/core/linux_amd64_core.go index b1eca1ef..e2f3257d 100644 --- a/pkg/proc/core/linux_amd64_core.go +++ b/pkg/proc/core/linux_amd64_core.go @@ -256,16 +256,23 @@ func readCore(corePath, exePath string) (*Core, error) { if err != nil { return nil, err } + exeELF, err := elf.NewFile(exe) + if err != nil { + return nil, err + } if coreFile.Type != elf.ET_CORE { return nil, fmt.Errorf("%v is not a core file", coreFile) } + if exeELF.Type != elf.ET_EXEC { + return nil, fmt.Errorf("%v is not an exe file", exeELF) + } notes, err := readNotes(coreFile) if err != nil { return nil, err } - memory := buildMemory(coreFile, exe, notes) + memory := buildMemory(coreFile, exeELF, exe, notes) core := &Core{ MemoryReader: memory, @@ -417,7 +424,7 @@ func skipPadding(r io.ReadSeeker, pad int64) error { return nil } -func buildMemory(core *elf.File, exe io.ReaderAt, notes []*Note) proc.MemoryReader { +func buildMemory(core, exeELF *elf.File, exe io.ReaderAt, notes []*Note) proc.MemoryReader { memory := &SplicedMemory{} // For now, assume all file mappings are to the exe. @@ -434,16 +441,21 @@ func buildMemory(core *elf.File, exe io.ReaderAt, notes []*Note) proc.MemoryRead } } - for _, prog := range core.Progs { - if prog.Type == elf.PT_LOAD { - if prog.Filesz == 0 { - continue - } - r := &OffsetReaderAt{ - reader: prog.ReaderAt, - offset: uintptr(prog.Vaddr), + + // Load memory segments from exe and then from the core file, + // allowing the corefile to overwrite previously loaded segments + for _, elfFile := range []*elf.File{exeELF, core} { + for _, prog := range elfFile.Progs { + if prog.Type == elf.PT_LOAD { + if prog.Filesz == 0 { + continue + } + r := &OffsetReaderAt{ + reader: prog.ReaderAt, + offset: uintptr(prog.Vaddr), + } + memory.Add(r, uintptr(prog.Vaddr), uintptr(prog.Filesz)) } - memory.Add(r, uintptr(prog.Vaddr), uintptr(prog.Filesz)) } } return memory -- GitLab