Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

debug: request goroutines from dlv only once per stop (in handleReenterDebug) #940

Closed
polinasok opened this issue Nov 19, 2020 · 0 comments
Labels
debug/legacy legacy debug adapter related issues - new issues won't be fixed Debug Issues related to the debugging functionality of the extension. FrozenDueToAge

Comments

@polinasok
Copy link
Contributor

polinasok commented Nov 19, 2020

As we know from #129, threads/goroutine requests can be quite expensive. We should avoid pulling duplicate information for these from the backend.

Vscode issues threads requests in the following cases without checking for dups like it does with thread events:

  • after configuration done request (source)
  • on a stopped event (source)

When the program stops on entry, we will get dups on entry. In this case the return list will be empty, so this won't be very expensive:

From client: configurationDone(undefined)
To client: {"seq":0,"type":"event","event":"stopped","body":{"reason":"entry","threadId":1}}
To client: {"seq":0,"type":"response","request_seq":7,"command":"configurationDone","success":true}
From client: threads(undefined)
   debug layer=rpc (async 19) <- RPCServer.State(rpc2.StateIn{"NonBlocking":true})
   debug layer=rpc (async 19) -> rpc2.StateOut{"State":{"Running":false,"Recording":false,"currentThread":{"id":816484,"pc":274972672,"file":"","line":0,"goroutineID":0,"ReturnValues":null},"Threads":[{"id":816484,"pc":274972672,"file":"","line":0,"goroutineID":0,"ReturnValues":null}],"NextInProgress":false,"exited":false,"exitStatus":0,"When":""}} error: ""
   debug layer=rpc <- RPCServer.ListGoroutines(rpc2.ListGoroutinesIn{"Start":0,"Count":0})
   debug layer=rpc -> *rpc2.ListGoroutinesOut{"Goroutines":[],"Nextg":-1} error: ""
To client: {"seq":0,"type":"response","request_seq":8,"command":"threads","success":true,"body":{"threads":[{"id":1,"name":"Dummy"}]}}
From client: threads(undefined) <================ DUP
   debug layer=rpc (async 21) <- RPCServer.State(rpc2.StateIn{"NonBlocking":true})
   debug layer=rpc (async 21) -> rpc2.StateOut{"State":{"Running":false,"Recording":false,"currentThread":{"id":816484,"pc":274972672,"file":"","line":0,"goroutineID":0,"ReturnValues":null},"Threads":[{"id":816484,"pc":274972672,"file":"","line":0,"goroutineID":0,"ReturnValues":null}],"NextInProgress":false,"exited":false,"exitStatus":0,"When":""}} error: ""
   debug layer=rpc <- RPCServer.ListGoroutines(rpc2.ListGoroutinesIn{"Start":0,"Count":0})
   debug layer=rpc -> *rpc2.ListGoroutinesOut{"Goroutines":[],"Nextg":-1} error: ""
To client: {"seq":0,"type":"response","request_seq":9,"command":"threads","success":true,"body":{"threads":[{"id":1,"name":"Dummy"}]}}

When a program doesn't stop on entry, the threads request that is issued along with configurationDone can arrive when a breakpoint is hit, which comes with its own threads request. And at that point there can be many goroutines to return:

From client: configurationDone(undefined)
   debug layer=rpc (async 19) <- RPCServer.State(rpc2.StateIn{"NonBlocking":true})
   debug layer=rpc (async 19) -> rpc2.StateOut{"State":{"Running":false,"Recording":false,"currentThread":{"id":834169,"pc":277549056,"file":"","line":0,"goroutineID":0,"ReturnValues":null},"Threads":[{"id":834169,"pc":277549056,"file":"","line":0,"goroutineID":0,"ReturnValues":null}],"NextInProgress":false,"exited":false,"exitStatus":0,"When":""}} error: ""
Changing DebugState from Halted to Running
To client: {"seq":0,"type":"response","request_seq":7,"command":"configurationDone","success":true}
   debug layer=rpc (async 20) <- RPCServer.Command(api.DebuggerCommand{"name":"continue","ReturnInfoLoadConfig":null})
   debug layer=debugger continuing
   debug layer=rpc (async 20) -> rpc2.CommandOut{"State":{"Running":false,"Recording":false,"currentThread":{"id":834169,"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false},"goroutineID":1,"breakPoint":{"id":3,"name":"","addr":17583771,"addrs":[17583771],"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"functionName":"main.main","Cond":"","continue":false,"traceReturn":false,"goroutine":false,"stacktrace":0,"LoadArgs":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"LoadLocals":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"hitCount":{"1":1},"totalHitCount":1},"breakPointInfo":{},"ReturnValues":null},"currentGoroutine":{"id":1,"currentLoc":{"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false}},"userCurrentLoc":{"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false}},"goStatementLoc":{"pc":17178422,"file":"/usr/local/go/src/runtime/asm_amd64.s","line":220,"function":{"name":"runtime.rt0_go","value":17178112,"type":0,"goType":0,"optimized":true}},"startLoc":{"pc":16998528,"file":"/usr/local/go/src/runtime/proc.go","line":113,"function":{"name":"runtime.main","value":16998528,"type":0,"goType":0,"optimized":true}},"threadID":834169,"unreadable":""},"Threads":[{"id":834169,"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false},"goroutineID":1,"breakPoint":{"id":3,"name":"","addr":17583771,"addrs":[17583771],"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"functionName":"main.main","Cond":"","continue":false,"traceReturn":false,"goroutine":false,"stacktrace":0,"LoadArgs":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"LoadLocals":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"hitCount":{"1":1},"totalHitCount":1},"breakPointInfo":{},"ReturnValues":null},{"id":834201,"pc":140735020791638,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834202,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834203,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834204,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834205,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null}],"NextInProgress":false,"exited":false,"exitStatus":0,"When":""}} error: ""
handleReenterDebug(breakpoint)
From client: threads(undefined)
   debug layer=rpc <- RPCServer.ListGoroutines(rpc2.ListGoroutinesIn{"Start":0,"Count":1})
   debug layer=rpc -> *rpc2.ListGoroutinesOut{"Goroutines":[{"id":1,"currentLoc":{"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false}},"userCurrentLoc":{"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false}},"goStatementLoc":{"pc":17178422,"file":"/usr/local/go/src/runtime/asm_amd64.s","line":220,"function":{"name":"runtime.rt0_go","value":17178112,"type":0,"goType":0,"optimized":true}},"startLoc":{"pc":16998528,"file":"/usr/local/go/src/runtime/proc.go","line":113,"function":{"name":"runtime.main","value":16998528,"type":0,"goType":0,"optimized":true}},"threadID":834169,"unreadable":""}],"Nextg":1} error: ""
   debug layer=rpc (async 22) <- RPCServer.State(rpc2.StateIn{"NonBlocking":true})
   debug layer=rpc (async 22) -> rpc2.StateOut{"State":{"Running":false,"Recording":false,"currentThread":{"id":834169,"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false},"goroutineID":1,"breakPoint":{"id":3,"name":"","addr":17583771,"addrs":[17583771],"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"functionName":"main.main","Cond":"","continue":false,"traceReturn":false,"goroutine":false,"stacktrace":0,"LoadArgs":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"LoadLocals":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"hitCount":{"1":1},"totalHitCount":1},"ReturnValues":null},"currentGoroutine":{"id":1,"currentLoc":{"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false}},"userCurrentLoc":{"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false}},"goStatementLoc":{"pc":17178422,"file":"/usr/local/go/src/runtime/asm_amd64.s","line":220,"function":{"name":"runtime.rt0_go","value":17178112,"type":0,"goType":0,"optimized":true}},"startLoc":{"pc":16998528,"file":"/usr/local/go/src/runtime/proc.go","line":113,"function":{"name":"runtime.main","value":16998528,"type":0,"goType":0,"optimized":true}},"threadID":834169,"unreadable":""},"Threads":[{"id":834203,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834204,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834205,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834169,"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false},"goroutineID":1,"breakPoint":{"id":3,"name":"","addr":17583771,"addrs":[17583771],"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"functionName":"main.main","Cond":"","continue":false,"traceReturn":false,"goroutine":false,"stacktrace":0,"LoadArgs":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"LoadLocals":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"hitCount":{"1":1},"totalHitCount":1},"ReturnValues":null},{"id":834201,"pc":140735020791638,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834202,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null}],"NextInProgress":false,"exited":false,"exitStatus":0,"When":""}} error: ""
To client: {"seq":0,"type":"event","event":"stopped","body":{"reason":"breakpoint","threadId":1,"allThreadsStopped":true}}
   debug layer=rpc <- RPCServer.ListGoroutines(rpc2.ListGoroutinesIn{"Start":0,"Count":0})
   debug layer=rpc -> *rpc2.ListGoroutinesOut{"Goroutines":[{"id":1,"currentLoc":{"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false}},"userCurrentLoc":{"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false}},"goStatementLoc":{"pc":17178422,"file":"/usr/local/go/src/runtime/asm_amd64.s","line":220,"function":{"name":"runtime.rt0_go","value":17178112,"type":0,"goType":0,"optimized":true}},"startLoc":{"pc":16998528,"file":"/usr/local/go/src/runtime/proc.go","line":113,"function":{"name":"runtime.main","value":16998528,"type":0,"goType":0,"optimized":true}},"threadID":834169,"unreadable":""},{"id":2,"currentLoc":{"pc":16999931,"file":"/usr/local/go/src/runtime/proc.go","line":305,"function":{"name":"runtime.gopark","value":16999728,"type":0,"goType":0,"optimized":true}},"userCurrentLoc":{"pc":16999931,"file":"/usr/local/go/src/runtime/proc.go","line":305,"function":{"name":"runtime.gopark","value":16999728,"type":0,"goType":0,"optimized":true}},"goStatementLoc":{"pc":16999381,"file":"/usr/local/go/src/runtime/proc.go","line":242,"function":{"name":"runtime.init.6","value":16999328,"type":0,"goType":0,"optimized":true}},"startLoc":{"pc":16999408,"file":"/usr/local/go/src/runtime/proc.go","line":245,"function":{"name":"runtime.forcegchelper","value":16999408,"type":0,"goType":0,"optimized":true}},"threadID":0,"unreadable":""},{"id":3,"currentLoc":{"pc":16999931,"file":"/usr/local/go/src/runtime/proc.go","line":305,"function":{"name":"runtime.gopark","value":16999728,"type":0,"goType":0,"optimized":true}},"userCurrentLoc":{"pc":16999931,"file":"/usr/local/go/src/runtime/proc.go","line":305,"function":{"name":"runtime.gopark","value":16999728,"type":0,"goType":0,"optimized":true}},"goStatementLoc":{"pc":16883916,"file":"/usr/local/go/src/runtime/mgc.go","line":214,"function":{"name":"runtime.gcenable","value":16883824,"type":0,"goType":0,"optimized":true}},"startLoc":{"pc":16920992,"file":"/usr/local/go/src/runtime/mgcsweep.go","line":64,"function":{"name":"runtime.bgsweep","value":16920992,"type":0,"goType":0,"optimized":true}},"threadID":0,"unreadable":""},{"id":4,"currentLoc":{"pc":16999931,"file":"/usr/local/go/src/runtime/proc.go","line":305,"function":{"name":"runtime.gopark","value":16999728,"type":0,"goType":0,"optimized":true}},"userCurrentLoc":{"pc":16999931,"file":"/usr/local/go/src/runtime/proc.go","line":305,"function":{"name":"runtime.gopark","value":16999728,"type":0,"goType":0,"optimized":true}},"goStatementLoc":{"pc":16883950,"file":"/usr/local/go/src/runtime/mgc.go","line":215,"function":{"name":"runtime.gcenable","value":16883824,"type":0,"goType":0,"optimized":true}},"startLoc":{"pc":16914192,"file":"/usr/local/go/src/runtime/mgcscavenge.go","line":225,"function":{"name":"runtime.bgscavenge","value":16914192,"type":0,"goType":0,"optimized":true}},"threadID":0,"unreadable":""},{"id":17,"currentLoc":{"pc":16999931,"file":"/usr/local/go/src/runtime/proc.go","line":305,"function":{"name":"runtime.gopark","value":16999728,"type":0,"goType":0,"optimized":true}},"userCurrentLoc":{"pc":16999931,"file":"/usr/local/go/src/runtime/proc.go","line":305,"function":{"name":"runtime.gopark","value":16999728,"type":0,"goType":0,"optimized":true}},"goStatementLoc":{"pc":16879729,"file":"/usr/local/go/src/runtime/mfinal.go","line":156,"function":{"name":"runtime.createfing","value":16879632,"type":0,"goType":0,"optimized":true}},"startLoc":{"pc":16879744,"file":"/usr/local/go/src/runtime/mfinal.go","line":161,"function":{"name":"runtime.runfinq","value":16879744,"type":0,"goType":0,"optimized":true}},"threadID":0,"unreadable":""}],"Nextg":-1} error: ""
To client: {"seq":0,"type":"response","request_seq":8,"command":"threads","success":true,"body":{"threads":[{"id":1,"name":"main.main"},{"id":2,"name":"runtime.gopark"},{"id":3,"name":"runtime.gopark"},{"id":4,"name":"runtime.gopark"},{"id":17,"name":"runtime.gopark"}]}}
From client: threads(undefined) <===================== DUP
   debug layer=rpc (async 24) <- RPCServer.State(rpc2.StateIn{"NonBlocking":true})
   debug layer=rpc (async 24) -> rpc2.StateOut{"State":{"Running":false,"Recording":false,"currentThread":{"id":834169,"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false},"goroutineID":1,"breakPoint":{"id":3,"name":"","addr":17583771,"addrs":[17583771],"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"functionName":"main.main","Cond":"","continue":false,"traceReturn":false,"goroutine":false,"stacktrace":0,"LoadArgs":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"LoadLocals":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"hitCount":{"1":1},"totalHitCount":1},"ReturnValues":null},"currentGoroutine":{"id":1,"currentLoc":{"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false}},"userCurrentLoc":{"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false}},"goStatementLoc":{"pc":17178422,"file":"/usr/local/go/src/runtime/asm_amd64.s","line":220,"function":{"name":"runtime.rt0_go","value":17178112,"type":0,"goType":0,"optimized":true}},"startLoc":{"pc":16998528,"file":"/usr/local/go/src/runtime/proc.go","line":113,"function":{"name":"runtime.main","value":16998528,"type":0,"goType":0,"optimized":true}},"threadID":834169,"unreadable":""},"Threads":[{"id":834169,"pc":17583771,"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"function":{"name":"main.main","value":17583744,"type":0,"goType":0,"optimized":false},"goroutineID":1,"breakPoint":{"id":3,"name":"","addr":17583771,"addrs":[17583771],"file":"/Users/polina/go/src/varsnew/vars.go","line":41,"functionName":"main.main","Cond":"","continue":false,"traceReturn":false,"goroutine":false,"stacktrace":0,"LoadArgs":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"LoadLocals":{"FollowPointers":true,"MaxVariableRecurse":1,"MaxStringLen":64,"MaxArrayValues":64,"MaxStructFields":-1},"hitCount":{"1":1},"totalHitCount":1},"ReturnValues":null},{"id":834201,"pc":140735020791638,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834202,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834203,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834204,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null},{"id":834205,"pc":140735020791938,"file":"","line":0,"goroutineID":0,"ReturnValues":null}],"NextInProgress":false,"exited":false,"exitStatus":0,"When":""}} error: ""
debug layer=rpc <- RPCServer.ListGoroutines(rpc2.ListGoroutinesIn{"Start":0,"Count":0})
...etc...

Also, if we fix handling of simultaneous breakpoints (#130), we will need to issue a stopped event per breakpoint, which will also trigger duplicate threads requests.

@polinasok polinasok added Debug Issues related to the debugging functionality of the extension. DelveDAP labels Nov 19, 2020
@gopherbot gopherbot added this to the Untriaged milestone Apr 8, 2021
@hyangah hyangah modified the milestones: Untriaged, Backlog Apr 14, 2021
@polinasok polinasok added debug/legacy legacy debug adapter related issues - new issues won't be fixed WillNotFix and removed DA: DlvDAP labels Apr 7, 2022
@golang golang locked and limited conversation to collaborators Apr 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
debug/legacy legacy debug adapter related issues - new issues won't be fixed Debug Issues related to the debugging functionality of the extension. FrozenDueToAge
Projects
None yet
Development

No branches or pull requests

3 participants