Is lldb-dap usable?

The very first run I did with lldb-dap (linux) caused a core dump. Is this usable yet? It was also awkward getting this to run. I’m writing an IDE and I’d like to support native code on windows and mac. I have gdb running on linux just fine but gdb doesn’t run on windows (with clang compiled binaries) or mac.

I have lldb version 20.1.7 installed. Here’s how I crashed lldb-dap, I did this on linux and haven’t tried on mac

First in the folder /tmp/test (you’ll need the correct path) I compiled the below using clang++ a.cpp -g

int main() {
    int a=0;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
    a++;
}

Put the following in a file such as dapIn

Content-Length: 543

{"command":"initialize","arguments":{"clientID":"vscode","clientName":"Visual Studio Code","adapterID":"lldb-dap","pathFormat":"path","linesStartAt1":true,"columnsStartAt1":true,"supportsVariableType":true,"supportsVariablePaging":true,"supportsRunInTerminalRequest":true,"locale":"en","supportsProgressReporting":true,"supportsInvalidatedEvent":true,"supportsMemoryReferences":true,"supportsArgsCanBeInterpretedByShell":true,"supportsMemoryEvent":true,"supportsStartDebuggingRequest":true,"supportsANSIStyling":true},"type":"request","seq":1}Content-Length: 255

{"command":"launch","arguments":{"type":"lldb-dap","request":"launch","name":"Debug","program":"/tmp/test/a.out","args":[],"env":[],"cwd":"/tmp/test","__configurationTarget":6,"__sessionId":"9a277144-44e6-4368-b6a8-ae1cea30191d"},"type":"request","seq":2}Content-Length: 206

{"command":"setBreakpoints","arguments":{"source":{"name":"a.cpp","path":"/tmp/test/a.cpp"},"lines":[4,21],"breakpoints":[{"line":4},{"line":21,"column":1}],"sourceModified":false},"type":"request","seq":3}Content-Length: 92

{"command":"setFunctionBreakpoints","arguments":{"breakpoints":[]},"type":"request","seq":4}Content-Length: 95

{"command":"setInstructionBreakpoints","arguments":{"breakpoints":[]},"type":"request","seq":5}Content-Length: 89

{"command":"setExceptionBreakpoints","arguments":{"filters":[]},"type":"request","seq":6}Content-Length: 88

{"command":"setDataBreakpoints","arguments":{"breakpoints":[]},"type":"request","seq":7}Content-Length: 56

{"command":"configurationDone","type":"request","seq":8}

Then run cat dapIn | lldb-dap, I got a 214mb core dump after running that

lldb-dap works great. We use it all the time at my company. In fact, last week I used it to track down a DWARF register ID mismatch between our compiler and simulator.

I don’t know about “cat dapIn | lldb-dap”, but we use it with the LLDB DAP extension from the vscode marketplace, which was set up by @JDevlieghere . Some of use use CodeLLDB, also on the marketplace, which was set up by @vadimcn .

What’s the backtrace from the crash?

Just to clarify, I implemented a debug adapter and the text above came from interactions with the vscode implementation. I’m not testing lldb-dap against my current code, I’m testing it with the input vscode gave it.

I’m on a different box right now and now I get no output, no errors, no core dump, no nothing. No other DAP has been as strange as this one but I haven’t tried the java dap yet (their LSP was strange.) I’ll look into this again in a few days but there shouldn’t be any reason why the same input has the dap behave differently on two machines, one crashing and one not doing anything, both a fail

I can reproduce the crash with an older version when piping text from stdin. Note that Discourse has stripped the carriage returns, so for the issue to reproduce, they need to be re-added manually. As @tedwoodward speculated, the issue seems specific to piping from stdin, the same version of lldb-dap works totally fine in VS Code, though I agree the crash shouldn’t happen.

A lot has changed in the transport layer since version 20 and indeed, the issue has been fixed on top-of-tree where it’s handled correctly.

It would be helpful if you could be more specific. If you can reproduce an issue with the ToT, please file an issue and include as much information as possible. For example, loading the core file into LLDB and including the stack trace would’ve been helpful here.

For example, loading the core file

I’ll keep that in mind for next time, I wasn’t sure if this project was an alpha or beta

No other DAP has been as strange as this one

It would be helpful if you could be more specific

You figured out 2 of the problems. The easier is the line ending being the problem. As you noticed I tested and saw the crash, but then failed to reproduce it later because I didn’t notice the line endings changed. There’s no error reply or error message on stderr to help me understand what went wrong.

I was able to track down the cause.
It happens in the destructor of DAP struct.

It is because the event_thread and progress_event_thread not being joined before calling DAP struct deconstructor.

Previously the event_thread and the progress_event_thread was only joined when we call the disconnect request.

It was fixed in this commit

Will create a PR tomorrow for the 20.x branch as it is quite late here.

There’s unlikely to be another 20.x release. LLVM 20.1.8 plans

A quick update

I spent a few minutes getting lldb-dap to run with my code. I’m able to run a simple binary without any obvious problems. I did notice it takes LONG to load. 1580ms when I send launch. It’s not the worse thing but it feels awkward when I’m use to faster, all my gdb test run in 100’s of ms and time gdb ./my-bin -batch -ex run takes 100-105ms, thats 15x faster which is why I noticed the difference immediately

I’ll tackle more dap and lldb-dap through the week

I’m able to run a simple binary without any obvious problems. I did notice it takes LONG to load. 1580ms when I send launch.

Please could you file an Issue with the reproducer as it would be easier to track.

There’s unlikely to be another 20.x release. LLVM 20.1.8 plans

In case there is no new release. here is a patch on the 20.x branch.
join_threads.patch (1.9 KB)

Done

I just wanted to write a quick follow up

I fixed that obnoxious start up time by blocking a specific domain through a host file. It was blocking for several seconds every run trying to look up symbol information, even when I had no breakpoints and ran a hello world app. I was trying to test if all my dap code worked correctly and I had to disable lldb-dap test until I was done implementing a feature. Once I realized it was a network issue I blocked the domain and now I can run the test every time

I would prefer getting error messages via stdin, however once I started assuming I hit a case where I gave it invalid json it no longer was a problem. I don’t think I hit an internal error or anything (although I have in other daps)