From dcf51a5032b6194fd4ed82f3c5bb65b85579172a Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 1 May 2017 18:57:37 +0200 Subject: [PATCH] proc/native: error when reading/writing memory of exited process (#812) Fixes #809 --- pkg/proc/gdbserial/gdbserver.go | 3 +++ pkg/proc/native/threads_darwin.go | 8 ++++++++ pkg/proc/native/threads_linux.go | 6 ++++++ pkg/proc/native/threads_windows.go | 6 ++++++ service/test/common_test.go | 7 +++++++ 5 files changed, 30 insertions(+) diff --git a/pkg/proc/gdbserial/gdbserver.go b/pkg/proc/gdbserial/gdbserver.go index 6ddc33d4..c9c7ad16 100644 --- a/pkg/proc/gdbserial/gdbserver.go +++ b/pkg/proc/gdbserial/gdbserver.go @@ -554,6 +554,9 @@ func (p *Process) StepInstruction() error { } func (p *Process) SwitchThread(tid int) error { + if p.exited { + return proc.ProcessExitedError{Pid: p.conn.pid} + } if th, ok := p.threads[tid]; ok { p.currentThread = th p.selectedGoroutine, _ = proc.GetG(p.CurrentThread()) diff --git a/pkg/proc/native/threads_darwin.go b/pkg/proc/native/threads_darwin.go index cc54ebd0..0104865f 100644 --- a/pkg/proc/native/threads_darwin.go +++ b/pkg/proc/native/threads_darwin.go @@ -8,6 +8,8 @@ import ( "unsafe" sys "golang.org/x/sys/unix" + + "github.com/derekparker/delve/pkg/proc" ) // WaitStatus is a synonym for the platform-specific WaitStatus @@ -105,6 +107,9 @@ func (t *Thread) stopped() bool { } func (t *Thread) WriteMemory(addr uintptr, data []byte) (int, error) { + if t.dbp.exited { + return 0, proc.ProcessExitedError{Pid: t.dbp.pid} + } if len(data) == 0 { return 0, nil } @@ -120,6 +125,9 @@ func (t *Thread) WriteMemory(addr uintptr, data []byte) (int, error) { } func (t *Thread) ReadMemory(buf []byte, addr uintptr) (int, error) { + if t.dbp.exited { + return 0, proc.ProcessExitedError{Pid: t.dbp.pid} + } if len(buf) == 0 { return 0, nil } diff --git a/pkg/proc/native/threads_linux.go b/pkg/proc/native/threads_linux.go index bea278ee..57700581 100644 --- a/pkg/proc/native/threads_linux.go +++ b/pkg/proc/native/threads_linux.go @@ -97,6 +97,9 @@ func (t *Thread) restoreRegisters() (err error) { } func (t *Thread) WriteMemory(addr uintptr, data []byte) (written int, err error) { + if t.dbp.exited { + return 0, proc.ProcessExitedError{Pid: t.dbp.pid} + } if len(data) == 0 { return } @@ -105,6 +108,9 @@ func (t *Thread) WriteMemory(addr uintptr, data []byte) (written int, err error) } func (t *Thread) ReadMemory(data []byte, addr uintptr) (n int, err error) { + if t.dbp.exited { + return 0, proc.ProcessExitedError{Pid: t.dbp.pid} + } if len(data) == 0 { return } diff --git a/pkg/proc/native/threads_windows.go b/pkg/proc/native/threads_windows.go index ce1bfaad..766be120 100644 --- a/pkg/proc/native/threads_windows.go +++ b/pkg/proc/native/threads_windows.go @@ -133,6 +133,9 @@ func (t *Thread) stopped() bool { } func (t *Thread) WriteMemory(addr uintptr, data []byte) (int, error) { + if t.dbp.exited { + return 0, proc.ProcessExitedError{Pid: t.dbp.pid} + } var count uintptr err := _WriteProcessMemory(t.dbp.os.hProcess, addr, &data[0], uintptr(len(data)), &count) if err != nil { @@ -144,6 +147,9 @@ func (t *Thread) WriteMemory(addr uintptr, data []byte) (int, error) { var ErrShortRead = errors.New("short read") func (t *Thread) ReadMemory(buf []byte, addr uintptr) (int, error) { + if t.dbp.exited { + return 0, proc.ProcessExitedError{Pid: t.dbp.pid} + } if len(buf) == 0 { return 0, nil } diff --git a/service/test/common_test.go b/service/test/common_test.go index 892d5212..6168363b 100644 --- a/service/test/common_test.go +++ b/service/test/common_test.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "runtime" + "strings" "testing" "github.com/derekparker/delve/service/api" @@ -24,6 +25,12 @@ func assertError(err error, t *testing.T, s string) { fname := filepath.Base(file) t.Fatalf("failed assertion at %s:%d: %s (no error)\n", fname, line, s) } + + if strings.Index(err.Error(), "Internal debugger error") >= 0 { + _, file, line, _ := runtime.Caller(1) + fname := filepath.Base(file) + t.Fatalf("failed assertion at %s:%d: %s internal debugger error: %v\n", fname, line, s, err) + } } func init() {