clayborg wrote:

So the issue from only the lldb-dap side here is VS Code is sending a threads 
request, but we have resumed the process upon attach after sending the 
configuration done request. So the race condition happens like:

- send configuration done
- send continue to process if stop on entry if false
- <start race condition>
  - Our event thread will at some point consume the `eStateRunning` and cause 
our public API to not allow stop locker requests to succeed, but any API calls 
that come through before we consume this event will succeed,
  - at the same time as the above event thread, we get a "threads" request and 
start calling `SBProcess::GetNumThreads()` and 
`SBProcess::GetThreadAtIndex(...)` and might get valid results if the run 
locker is allowing stopped process calls. so we may start getting the number of 
threads and some threads by index, but any of these calls can fail as soon as 
we consume the `eStateRunning` process event in lldb-dap

So from a DAP only perspective, we need to sync with our lldb-dap event thread. 
Current code looks like:
```
void ConfigurationDoneRequestHandler::operator()(
    const llvm::json::Object &request) const {
  llvm::json::Object response;
  FillResponse(request, response);
  dap.SendJSON(llvm::json::Value(std::move(response)));
  dap.configuration_done_sent = true;
  if (dap.stop_at_entry)
    SendThreadStoppedEvent(dap);
  else
    dap.target.GetProcess().Continue();
}
```
But probably should look like:
```
void ConfigurationDoneRequestHandler::operator()(
    const llvm::json::Object &request) const {
  llvm::json::Object response;
  FillResponse(request, response);
  dap.SendJSON(llvm::json::Value(std::move(response)));
  dap.configuration_done_sent = true;
  if (dap.stop_at_entry)
    SendThreadStoppedEvent(dap);
  else {
    dap.target.GetProcess().Continue();
    dap.WaitForProcessResumedEvent(); /// New sync point here!
  }
}

```

The call to `dap.WaitForProcessResumedEvent()` will make sure we have received 
the `eStateRunning` process event before continuing. Then the "threads" call 
can fail as the process stop locker won't succeed for the 
`SBProcess::GetNumThreads()` and `SBProcess::GetThreadAtIndex(....)` calls. 
Once we get past this race, we are good, but again, only from the DAP 
perspective.

The fact that GetNumThreads() is able to interrupt (send a CTRL+C) to the 
lldb-server is another bug that needs fixing. I thought that only the 
breakpoint setting code would interrupt a process and send GDB remote packets 
while running. Why are we allowing the threads request to interrupt?


https://github.com/llvm/llvm-project/pull/134339
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to