• H
    dap: change how noDebug launch request is served (#2407) · da27e342
    Hyang-Ah Hana Kim 提交于
    * dap: change how noDebug launch request is served
    
    PR #2400 added support for noDebug launch requests - that was done
    by directly starting the target program using os/exec.Cmd and blocking
    the launch request indefinitely until the program terminates or
    is stopped with a disconnect request (when dlv dap can support it).
    Even though the approach seemed to work for user, that adds an extra
    control flow and complexity to the codebase.
    
    This change takes a different approach to implement the noDebug
    launch feature. Instead of using os/exec.Cmd, this uses the existing
    debug launch path, but avoids setting breakpoints. Finally, the program
    will start upon receiving onConfigurationDoneRequest and blocks there
    until the program terminates. This simplifies the code.
    
    The DAP spec does not explicitly specify what to do about other
    requests. It seems like VSCode can issue evaluate requests or other
    requests after the configuration done request. Currently they are
    blocked because the program is in running state. We can consider checking
    s.noDebug and responding with an error in the future if we want/need to.
    
    See the log below for a typical DAP request/response sequence:
    
    2021-03-29T01:42:53-04:00 debug layer=dap building binary at /Users/hakim/projects/s/__debug_bin
    2021-03-29T01:42:55-04:00 info layer=debugger launching process with args: [/Users/hakim/projects/s/__debug_bin]
    2021-03-29T01:42:55-04:00 debug layer=dap [-> to client]{"seq":0,"type":"event","event":"initialized"}
    2021-03-29T01:42:55-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":2,"success":true,"command":"launch"}
    2021-03-29T01:42:55-04:00 debug layer=dap [<- from client]{"seq":3,"type":"request","command":"setBreakpoints","arguments":{"source":{"name":"main.go","path":"/Users/hakim/projects/s/main.go"},"breakpoints":[{"line":9}],"lines":[9]}}
    2021-03-29T01:42:55-04:00 error layer=dap Unable to set or clear breakpoints: running in noDebug mode
    2021-03-29T01:42:55-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":3,"success":false,"command":"setBreakpoints","message":"Unable to set or clear breakpoints","body":{"error":{"id":2002,"format":"Unable to set or clear breakpoints: running in noDebug mode"}}}
    2021-03-29T01:42:55-04:00 debug layer=dap [<- from client]{"seq":4,"type":"request","command":"configurationDone","arguments":{}}
    2021-03-29T01:42:55-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":4,"success":true,"command":"configurationDone"}
    2021-03-29T01:42:55-04:00 debug layer=debugger continuing
    Hello
    2021-03-29T01:43:00-04:00 debug layer=dap [-> to client]{"seq":0,"type":"event","event":"terminated","body":{}}
    2021-03-29T01:43:00-04:00 debug layer=dap [<- from client]{"seq":5,"type":"request","command":"threads"}
    2021-03-29T01:43:00-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":5,"success":true,"command":"threads","body":{"threads":null}}
    2021-03-29T01:43:00-04:00 debug layer=dap [<- from client]{"seq":6,"type":"request","command":"disconnect","arguments":{}}
    2021-03-29T01:43:00-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":6,"success":true,"command":"disconnect"}
    2021-03-29T01:43:00-04:00 debug layer=debugger halting
    2021-03-29T01:43:00-04:00 error layer=dap Process 27219 has exited with status 0
    2021-03-29T01:43:00-04:00 debug layer=debugger detaching
    
    Updates https://github.com/golang/vscode-go/issues/1111
    
    * service/dap: address polina's comments for noDebug logic
    
    Reworked so the noDebug launch request again blocks launch request
    handler after responding with the launch response. By skipping
    the initialized event, it should prevent well-behaving clients from
    sending any further requests. Currently, doesn't matter because
    the handler goroutine will be blocked until the program termination
    anyway.
    
    Placed mutex back, since I noticed that's the only way to prevent
    racing between Stop and the handler goroutine. The synchronization
    lotic (in particular, during teardown) should be revisited after
    asynchronous request support work is done.
    
    * dap: address more comments
    da27e342
server.go 58.6 KB