From 5bf58b3adeeb41ad64b7ab229393617b8a75c947 Mon Sep 17 00:00:00 2001 From: aarzilli Date: Wed, 26 Jun 2024 10:54:03 +0200 Subject: [PATCH] service/debugger: evaluate breakpoint vars on g-less threads Use a thread scope to evaluate breakpoint variables if the current thread does not have an associated goroutine. Fixes #3758 --- cmd/dlv/dlv_test.go | 2 +- service/debugger/debugger.go | 8 +++++++- service/test/integration2_test.go | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go index 9d3cea6924..c9fd264102 100644 --- a/cmd/dlv/dlv_test.go +++ b/cmd/dlv/dlv_test.go @@ -1082,7 +1082,7 @@ func TestTraceBreakpointExists(t *testing.T) { // We always set breakpoints on some runtime functions at startup, so this would return with // a breakpoints exists error. // TODO: Perhaps we shouldn't be setting these default breakpoints in trace mode, however. - cmd := exec.Command(dlvbin, "trace", "--output", filepath.Join(t.TempDir(), "__debug"), filepath.Join(fixtures, "issue573.go"), "runtime.*") + cmd := exec.Command(dlvbin, "trace", "--output", filepath.Join(t.TempDir(), "__debug"), filepath.Join(fixtures, "issue573.go"), "runtime.*panic") rdr, err := cmd.StderrPipe() assertNoError(err, t, "stderr pipe") defer rdr.Close() diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index a130efa288..e0bf2fa2d3 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -1388,7 +1388,13 @@ func (d *Debugger) collectBreakpointInformation(apiThread *api.Thread, thread pr s, err := proc.GoroutineScope(tgt, thread) if err != nil { - return err + var errNoGoroutine proc.ErrNoGoroutine + if errors.As(err, &errNoGoroutine) { + s, err = proc.ThreadScope(tgt, thread) + } + if err != nil { + return err + } } if len(bp.Variables) > 0 { diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index b4b78692ac..6fc5f642d9 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -3153,3 +3153,17 @@ func TestNextInstruction(t *testing.T) { } }) } + +func TestBreakpointVariablesWithoutG(t *testing.T) { + // Tests that evaluating variables on a breakpoint that is hit on a thread + // without a goroutine does not cause an error. + withTestClient2("math", t, func(c service.Client) { + _, err := c.CreateBreakpoint(&api.Breakpoint{ + FunctionName: "runtime.mallocgc", + LoadArgs: &normalLoadConfig, + }) + assertNoError(err, t, "CreateBreakpoint") + state := <-c.Continue() + assertNoError(state.Err, t, "Continue()") + }) +}