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
}