cmd/viewcore: don't panic because of missing executable This exposes a new error type ExecNotFoundError to allow the viewcore main binary to recognize the error type and suggest --exe flag defined in the main package. Fixes golang/go#27322 Change-Id: I009b0cb9833a64b7cd5cba69b2ecc49327917581 Reviewed-on: https://go-review.googlesource.com/136516 Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/cmd/viewcore/main.go b/cmd/viewcore/main.go index 2495458..1ffeee2 100644 --- a/cmd/viewcore/main.go +++ b/cmd/viewcore/main.go
@@ -258,6 +258,9 @@ return nil, nil, err } p, err := gocore.Core(c) + if _, ok := err.(*core.ExecNotFoundError); ok && cfg.exePath == "" { + return nil, nil, fmt.Errorf("%v; consider specifying the --exe flag", err) + } if err != nil { return nil, nil, err }
diff --git a/internal/core/process.go b/internal/core/process.go index f6c4a3e..f1b49f2 100644 --- a/internal/core/process.go +++ b/internal/core/process.go
@@ -34,9 +34,10 @@ base string // base directory from which files in the core can be found exePath string // user-supplied main executable path - exec []*os.File // executables (more than one for shlibs) - mappings []*Mapping // virtual address mappings - threads []*Thread // os threads (TODO: map from pid?) + origExePath string // main executable path found in the core, set by readCore + exec []*os.File // executables (more than one for shlibs) + mappings []*Mapping // virtual address mappings + threads []*Thread // os threads (TODO: map from pid?) arch string // amd64, ... ptrSize int64 // 4 or 8 @@ -373,7 +374,6 @@ filenames := string(desc[3*8*count:]) desc = desc[:3*8*count] - origExePath := "" for i := uint64(0); i < count; i++ { min := Address(e.ByteOrder.Uint64(desc)) desc = desc[8:] @@ -394,7 +394,7 @@ // Assume the first entry is the main binary. if i == 0 { - origExePath = name + p.origExePath = name } var backing *os.File @@ -403,7 +403,7 @@ // If the name matches the cached original executable path // and user-provided executable is available, use the // user-provided one. - if p.exePath != "" && origExePath == name { + if p.exePath != "" && p.origExePath == name { backing, err = os.Open(p.exePath) } else { backing, err = os.Open(filepath.Join(p.base, name)) @@ -594,9 +594,24 @@ p.dwarf = dwarf } } + if p.dwarf == nil && p.dwarfErr == nil { + exe := p.origExePath + if p.exePath != "" { + exe = p.exePath + } + p.dwarfErr = &ExecNotFoundError{exe} + } return nil } +type ExecNotFoundError struct { + path string +} + +func (e *ExecNotFoundError) Error() string { + return fmt.Sprintf("missing executable %q", e.path) +} + func (p *Process) Warnings() []string { return p.warnings }