[lldb] Intermittent liblldb access violation (0xC0000005) on disconnect/detach after an attached session (Windows)
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## Environment
- lldb-dap **22.1.8**, revision `ca7933e47d3a3451d81e72ac174dcb5aa28b59d1`, Windows 11 (x86_64).
- Build: `-DLLDB_ENABLE_PYTHON=OFF -DLLDB_ENABLE_LUA=OFF`, **Release** (no `liblldb.pdb`), plus the
lazy PDB/SymbolFile memory patch (see `upstream/draft-pr-lazy-pdbindex.md` in the repro repo below — an upstream PR is being prepared). Whether the crash
reproduces on a stock build is untested.
- Debuggee: a running Unreal Engine 5.8 editor (`UnrealEditor.exe`), attached via
`attachCommands: ["process attach --pid "]`, `symbols.load-on-demand true`.
## Summary
During a `disconnect` request with `terminateDebuggee=false`, liblldb crashed with an access
violation (`0xC0000005`) inside its own code. The LLVM crash handler printed the backtrace to the DAP
console, **no `disconnect` response was ever emitted**, and the adapter process died. Because the
detach did not complete, the breakpoint's `int3` was left un-restored in the debuggee, which then
crashed on the next execution of that address.
## Frequency
**Intermittent — observed 1 out of 8 detach attempts.** It did *not* reproduce in 7 other detaches:
three with the breakpoint cleared before `disconnect` and ~3-minute soaks, one short-session detach,
one that approximated the long-session conditions (attach + 300 s soak + 8 breakpoint hits +
uncleared-bp disconnect), and **two that reproduced the exact original conditions (attach +
25-minute soak + 5+3 breakpoint hits + uncleared-bp disconnect)** — all completed cleanly in ~0.1 s
with the `int3` functionally restored (the breakpoint line subsequently executed with no exception and the
editor survived; site bytes were not read back directly). The exact trigger is unknown; the single crash
occurred on the uncleared-breakpoint + 25-minute-soak path, which has now been run **3 times total
(1 crash, 2 clean)**.
## Steps to reproduce (the one occurrence)
1. Attach lldb-dap to a running `UnrealEditor.exe` (LOD on).
2. `setBreakpoints` on a source line that fires every game tick; hit it 5 times (hit → continue).
3. Idle ~25 minutes with the process running (breakpoint cleared during the soak).
4. Re-set the same breakpoint; hit it 3 more times; `continue` (breakpoint **left set**).
5. `disconnect {"terminateDebuggee": false}`.
→ liblldb AV, crash backtrace on the console, no disconnect response.
## Crash backtrace
Verbatim excerpt in `realbed/h10_run1_crash_excerpt.txt` (DAP console output right after the
`disconnect` request, `seq 41`):
```
Exception Code: 0xC0000005
0x00007FFF488A3C07, liblldb.dll + 0x433C07, SetWatchpointTypeWrite(...) + 0x242237
0x00007FFF4886E86C, liblldb.dll + 0x3FE86C, SetWatchpointTypeWrite(...) + 0x20CE9C
0x00007FFF48877AF1, liblldb.dll + 0x407AF1, SetWatchpointTypeWrite(...) + 0x216121
0x00007FFF4886643B, liblldb.dll + 0x3F643B, SetWatchpointTypeWrite(...) + 0x204A6B
0x00007FFF4885DC97, liblldb.dll + 0x3EDC97, SetWatchpointTypeWrite(...) + 0x1FC2C7
0x00007FFF488520AD, liblldb.dll + 0x3E20AD, SetWatchpointTypeWrite(...) + 0x1F06DD
0x00007FFF4885945D, liblldb.dll + 0x3E945D, SetWatchpointTypeWrite(...) + 0x1F7A8D
0x00007FFF48758BCE, liblldb.dll + 0x2E8BCE, SetWatchpointTypeWrite(...) + 0xF71FE
0x00007FF8EF29CD30, ucrtbase.dll + 0x2CD30, wcsrchr() + 0x150
0x00007FF8F099E957, KERNEL32.DLL, BaseThreadInitThunk() + 0x17
0x00007FF8F18CAD6C, ntdll.dll, RtlUserThreadStart() + 0x2C
```
**Symbolization caveat:** this is a Release liblldb with no PDB, so `SetWatchpointTypeWrite`
(`SBWatchpointOptions`) is merely the *nearest exported symbol*; the large `+0x…` offsets mean the
faulting frames are internal functions, not that API.
The `ucrtbase!wcsrchr` frame (a reverse wide-string search) suggests a path/string operation during
detach — a plausible area is symbol-file path handling while removing breakpoint sites. A
debug-info build would be needed to resolve the real frames.
## Impact
A crash mid-detach leaves the software breakpoint's `int3` patched in the debuggee. With
`terminateDebuggee=false` the debuggee keeps running and hits the orphaned `int3` with no debugger
owning it → the debuggee terminates (observed: the editor survived the immediate detach window, then
exited with code 3 when the orphaned int3 address was next executed — observed shortly after a
subsequent re-attach).
## Normal (non-crashing) path, for contrast
A clean `disconnect {terminateDebuggee:false}` normally returns in ~0.1 s and functionally restores
the `int3` (the breakpoint line subsequently executed with no exception and the editor survived;
site bytes were not read back directly; consistent with `Process::Detach` → `DisableAllBreakpointSites`);
the debuggee survives and keeps running (measured repeatedly — 7 clean detaches, including two full
25-minute-soak + uncleared-bp runs). So this is an intermittent fault in the detach path, not the
expected behavior.
## Ask
Guidance on capturing a symbolicated backtrace (a `RelWithDebInfo` liblldb repro) and on whether the
detach-time breakpoint-site removal path has known races on Windows. Reproduction harnesses and clean
comparison runs in the companion repro repo https://github.com/cherleey/lldb-ue-pdb-repro :
`realbed/realbed_h10*_probe.py`, `realbed/realbed_h10{,b,c,d}_result.json`, and the
exact-condition 25-minute-soak repros `realbed/realbed_h15_probe.py` + `realbed/realbed_h15_run{1,2}_result.json`.
Contributor guide
Research direction
Build a RelWithDebInfo liblldb first, then run the exact-condition harnesses in realbed/realbed_h15_probe.py and compare their result JSON files with the crash excerpt. Trace the Windows detach path around Process::Detach and DisableAllBreakpointSites, using the symbolicated backtrace to determine whether breakpoint-site removal or symbol-file path handling is involved. Done means the fault is localized and clean disconnect restores the breakpoint without crashing the adapter or debuggee.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- devtools, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100