proc: refresh cur thread/sel g after ContineOnce errors (#2081)

On platforms other than macOS this doesn't matter but on macOS a
segmentation fault will cause ContinueOnce to return an error, before
returning it we should still fix the current thread and selected
goroutine values.

Fixes #2078
This commit is contained in:
Alessandro Arzilli 2020-06-11 20:46:00 +02:00 committed by GitHub
parent 708eadd553
commit 67f6a21ab8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 0 deletions

10
_fixtures/issue2078.go Normal file

@ -0,0 +1,10 @@
package main
func main() {
f(nil) //break
println("ok")
}
func f(x *int) {
println(*x)
}

@ -4809,3 +4809,27 @@ func TestStepIntoWrapperForEmbeddedPointer(t *testing.T) {
}
}
func TestRefreshCurThreadSelGAfterContinueOnceError(t *testing.T) {
// Issue #2078:
// Tests that on macOS/lldb the current thread/selected goroutine are
// refreshed after ContinueOnce returns an error due to a segmentation
// fault.
if runtime.GOOS != "darwin" && testBackend != "lldb" {
t.Skip("not applicable")
}
withTestProcess("issue2078", t, func(p *proc.Target, fixture protest.Fixture) {
setFileBreakpoint(p, t, fixture.Source, 4)
assertNoError(p.Continue(), t, "Continue() (first)")
if p.Continue() == nil {
t.Fatalf("Second continue did not return an error")
}
g := p.SelectedGoroutine()
if g.CurrentLoc.Line != 9 {
t.Fatalf("wrong current location %s:%d (expected :9)", g.CurrentLoc.File, g.CurrentLoc.Line)
}
})
}

@ -71,6 +71,17 @@ func (dbp *Target) Continue() error {
trapthread, stopReason, err := dbp.proc.ContinueOnce()
dbp.StopReason = stopReason
if err != nil {
// Attempt to refresh status of current thread/current goroutine, see
// Issue #2078.
// Errors are ignored because depending on why ContinueOnce failed this
// might very well not work.
if valid, _ := dbp.Valid(); valid {
if trapthread != nil {
_ = dbp.SwitchThread(trapthread.ThreadID())
} else if curth := dbp.CurrentThread(); curth != nil {
dbp.selectedGoroutine, _ = GetG(curth)
}
}
return err
}
if dbp.StopReason == StopLaunched {