[Lldb-commits] [PATCH] D119548: [lldb] Fix race condition between lldb-vscode and stop hooks executor

Ilya Nozhkin via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Fri Feb 11 07:49:45 PST 2022


ilya-nozhkin created this revision.
ilya-nozhkin added reviewers: jingham, clayborg.
ilya-nozhkin requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

The race is between these two pieces of code that are executed in two separate
lldb-vscode threads (the first is in the main thread and another is in the
event-handling thread):

  // lldb-vscode.cpp
  g_vsc.debugger.SetAsync(false);
  g_vsc.target.Launch(launch_info, error);
  g_vsc.debugger.SetAsync(true);



  // Target.cpp
  bool old_async = debugger.GetAsyncExecution();
  debugger.SetAsyncExecution(true);
  debugger.GetCommandInterpreter().HandleCommands(GetCommands(), exc_ctx,
                                                  options, result);
  debugger.SetAsyncExecution(old_async);

The sequence that leads to the bug is this one:

1. Main thread enables synchronous mode and launches the process.
2. When the process is launched, it generates the first stop event.
3. This stop event is catched by the event-handling thread and DoOnRemoval is invoked.
4. Inside DoOnRemoval, this thread runs stop hooks. And before running stop hooks, the current synchronization mode is stored into old_async (and right now it is equal to "false").
5. The main thread finishes the launch and returns to lldb-vscode, the synchronization mode is restored to asynchronous by lldb-vscode.
6. Event-handling thread finishes stop hooks processing and restores the synchronization mode according to old_async (i.e. makes the mode synchronous)
7. And now the mode is synchronous while lldb-vscode expects it to be asynchronous. Synchronous mode forbids the process to broadcast public stop events, so, VS Code just hangs because lldb-vscode doesn't notify it about stops.

So, this diff introduces a lock of synchronization mode for cases when it should
be saved before some action and then restored.

The bug is only present on Windows but it seems to be just a coincidence. On
Linux, as I understand, the first stop event is intercepted by hijacking
listener and is never popped out of the queue, so, stop hooks are not executed
and the race doesn't happen.

So, this diff also fixes some problems with lldb-vscode tests on Windows to make
it possible to run the related test. Other tests still can't be enabled because
the debugged program prints something into stdout and LLDB can't intercept this
output and redirect it to lldb-vscode properly.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D119548

Files:
  lldb/include/lldb/Core/Debugger.h
  lldb/include/lldb/Interpreter/CommandInterpreter.h
  lldb/packages/Python/lldbsuite/test/lldbtest.py
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
  lldb/source/Core/Debugger.cpp
  lldb/source/Interpreter/CommandInterpreter.cpp
  lldb/source/Target/Target.cpp
  lldb/test/API/tools/lldb-vscode/stop-hooks/Makefile
  lldb/test/API/tools/lldb-vscode/stop-hooks/TestVSCode_stop_hooks.py
  lldb/test/API/tools/lldb-vscode/stop-hooks/main.c

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D119548.407876.patch
Type: text/x-patch
Size: 17949 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20220211/fcca47ab/attachment-0001.bin>


More information about the lldb-commits mailing list