service/debugger: evaluate breakpoint vars on g-less threads (#3759)

Use a thread scope to evaluate breakpoint variables if the current
thread does not have an associated goroutine.

Fixes #3758
This commit is contained in:
Alessandro Arzilli 2024-07-01 20:23:39 +02:00 committed by GitHub
parent 608eaa3d7c
commit 979e487ac7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 22 additions and 2 deletions

@ -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()

@ -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 {

@ -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()")
})
}