Author Topic: LLDB debugger low level interface investigation results  (Read 19141 times)

Offline AndrewCot

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 678
LLDB debugger low level interface investigation results
« on: April 15, 2022, 08:50:43 am »
I have come to the conclusion that the LLDB debugger docs suck big time compared to the GDB manual that has all of the info in the one spot and at least it explains how things work and gives examples of inputs and some outputs. I cannot find anything like this for LLDB.

I have investigated the different ways of "controlling" the LLDB debugger and they are:
  • Direct via the command line like the GDB annotations does
  • Via a LLDB/MI executable that is no longer part of the LLVM project, but a third party product now.
  • Via the LLDB Scripting Bridge API (LLDB SB API)
This is what I have learnt from my investigations:
  • The LLDB command line is not documented enough to write a plugin easily and it also NOT guaranteed to be stable (aka not change). As such this is not viable IMHO.
  • The LLDB/MI has a number of issues and is not fully compatible with the GDB/MI interface that it says it is. I could not get a s simple break point did not work that worked via GDB or via the LLDB command line. As such this has too many issues to consider being viable.
  • The LLDB SB API is used by CodeLite and other IDE's. as per the docs "The SB APIs constitute the stable C++ API that LLDB presents to external clients....", so it should not change too much, if at all.  Below is a simple example I found on the web and have been able to build and run to test the LLDB SB API.
Code
// https://github.com/llvm/llvm-project/issues/52769#include <lldb/API/LLDB.h>
#include <windows.h>
#include <iostream>

using namespace lldb;

int main()
{
    SBDebugger::Initialize();
    auto debugger = SBDebugger::Create(true);
    debugger.SetAsync(false);

    auto const appPath = R"(D:\\Andrew_Development\\Z_Testing_Apps\\Clang_printf\\bin\\clang_Printf.exe)";  // Path to the program being debugged
    auto target = debugger.CreateTarget(appPath);

    auto breakpoint = target.BreakpointCreateByLocation("main.cpp", 45);  // Breakpoint location in the program being debugged
    auto breakpointExit = target.BreakpointCreateByLocation("main.cpp", 153);  // Breakpoint location in the program being debugged

    auto process = target.LaunchSimple(nullptr, nullptr, nullptr);

    while (true)
    {
        process.Continue();
        auto const count = breakpoint.GetHitCount();
        if (count % 10 == 0)
        {
            std::cout << count << " ";  // We just print the number of times the breakpoint was hit every 100 times
        }
        auto const countExit = breakpointExit.GetHitCount();
        if (countExit != 0)
        {
            break;
        }

    }

    SBDebugger::Terminate();

printf("EXITING!!!!!!!");
    return 0;
}


« Last Edit: April 18, 2022, 01:54:06 am by AndrewCot »

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9693
Re: LLDB debugger low level interface investigation results
« Reply #1 on: April 15, 2022, 10:40:57 am »
Thats interesting.
Strange the way they take with  LLDB/MI... but probably there is a good reason for it.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3352
Re: LLDB debugger low level interface investigation results
« Reply #2 on: April 15, 2022, 04:44:03 pm »
Interesting. Thank you for reporting.
Are the calls (for example process.Continue();)  blocking or not blocking?

Offline eranif

  • Regular
  • ***
  • Posts: 256
Re: LLDB debugger low level interface investigation results
« Reply #3 on: April 15, 2022, 06:42:45 pm »
Hi C::B team,

I rarely post on this forum, but I couldn't help noticing the discussion about LLDB (and the path that I took with CodeLite)
However, I would not take this path today. In fact the future of the debuggers, is similar to code completion: via dedicated small servers.

Today, most of the IDEs (including CodeLite) is using LSP (Language-Server-Protocol) for getting code completion via various implementations (clangd, rust-analyzer, pylsp etc)

The same revolution is taking place for the debuggers using the DAP protocol (Debug-Adapter-Protocol)

https://microsoft.github.io/debug-adapter-protocol/

I would recommend your to consider this path before investing time in using LLDB API directly


Eran

Offline AndrewCot

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 678
Re: LLDB debugger low level interface investigation results
« Reply #4 on: April 16, 2022, 02:13:54 am »
Eran,

Thanks for the info.

I did not investigate the DAP, but will now have a look.

Thanks,Andrew

 

Offline AndrewCot

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 678
Re: LLDB debugger low level interface investigation results
« Reply #5 on: April 16, 2022, 05:10:31 am »
I have looked at the DAP and it looks like the way to go as once implemented will then allow C::B to support in theory all of the debuggers listed on the following page:   https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/
Now comes the hard part, where to start over the next week and then restart and hopefully get a handle on the work I hope.


Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5514
Re: LLDB debugger low level interface investigation results
« Reply #6 on: April 17, 2022, 02:20:51 pm »
Hi Eran

many thanks for the information
very much appreciated  :)

Cheers

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3352
Re: LLDB debugger low level interface investigation results
« Reply #7 on: April 17, 2022, 09:07:32 pm »
I have looked at the DAP and it looks like the way to go as once implemented will then allow C::B to support in theory all of the debuggers listed on the following page:   https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/
Now comes the hard part, where to start over the next week and then restart and hopefully get a handle on the work I hope.

Have you found an gdb server? I am quite confused with the architecture or more, where to get the debugger servers. Are thy embedded in VS code and not stand alone?

Offline AndrewCot

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 678
Re: LLDB debugger low level interface investigation results
« Reply #8 on: April 18, 2022, 01:55:30 am »
I am playing with the following library/libraries to plug the DAP interface code hole:
https://github.com/google/cppdap
https://github.com/stoianmihail/cppdap-debugger

I am using the following DAP LLDB adapter for testing:
https://github.com/vadimcn/vscode-lldb

You will need to extract the https://github.com/vadimcn/vscode-lldb/releases/download/v1.7.0/codelldb-x86_64-windows.vsix file using 7zip. I run the adapter using the following command:
Code
adapter\codelldb --port 12345

I have not looked at how VSCode starts the different DAP adapters as I want to get something "working" first. "Working" is load an exe, set a break point on a line, run and hit the break point then run to the end of the hello world type app.

Attached in the 7z is my sample test project inc source that has a a hacked source code sample (LLDB_Client_Test.cpp) that uses bits from both github "cppdap" repos, but the launch step does not return or show anything. It does show the DAP adapter initialize request results, so at least I know the app and DAP adapter are communicating.

The following is a quick guide to build the cppdap library using MSYS2:

The Code::Blocks Debugger Application Protocol debugger plugin uses the following libraries:
    * https://github.com/google/cppdap

Use the following steps to build the cppdap library using MSYS2:

1. Clone the repo using the following command:
  * git clone --recurse-submodules https://github.com/google/cppdap

2. Generate the makefile:

bash
cd <path-to-cppdap>
mkdir build
cd build

cmake .. -G "MSYS Makefiles"

3. Finally, build the project:

make


P.S. One thing I spotted yesterday that I need to get my head around is that the DAP protocol launch request spec as it has the following in the spec, so then it makes the IDE only able to launch DAP adapters that it knows about as the launch arguments are specific to the DAP adapter.... I hope this is not the case, but this definitely needs more investigation to see how the launch request is implemented in IDE's.

"Since launching is debugger/runtime specific, the arguments for this request are not part of this specification."

Hope this is helpful.

Offline eranif

  • Regular
  • ***
  • Posts: 256
Re: LLDB debugger low level interface investigation results
« Reply #9 on: June 21, 2022, 01:11:35 am »
A quick update on this subject:

Since our chat here, I revived my 2 years old project "dbgd"

My goal was to create dap-gdb and dap-client, due to lack of time I paused my work on that.
Recently, I moved to develop full time on Mac and I needed a better lldb support (replacing my current lldb implementation which uses liblldb.dylib directly)

So with small effort I made dapcxx library that it built for wxWidgets.

All the interaction is done via events, i.e. whenever a an event / response arrives from the dap server, the GUI is notified via event (all the reads are done in a background thread)

You can check it out here:
https://github.com/eranif/dbgd -> it is a complete standalone library with zero dependencies (other than wxWidgets)
It comes with a small UI that demonstrate how to use it

The DAP server initialization is done here:
https://github.com/eranif/dbgd/blob/master/dbgcli/MainFrame.cpp#L59

PS:
You can install lldb-vscode from MSYS2 to try it out

Hope you will find it useful for your purposes

Eran

Offline AndrewCot

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 678
Re: LLDB debugger low level interface investigation results
« Reply #10 on: June 21, 2022, 05:02:22 am »
Thanks for the post as it will help.

I looked at your repo's a long time ago and seen it was a few years old and did not spend allot of time figuring out how it worked. I will have another look and spend time figuring it out.
I did not see that MSYS2 has the lldb-vscode as I downloaded the official release for it from the src git repo and started it. I will switch to the MSYS2 version.

Offline AndrewCot

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 678
Re: LLDB debugger low level interface investigation results
« Reply #11 on: June 24, 2022, 06:04:22 am »
Eran,

I have just successfully modified my local C::B for the following:a) Created a debugger_WXDAP.dll that is the dap dll and right now is in the same directory as the codeblocks.exe.
b) Created a new debugger plugin debugger_dap.dll that is wired in like the other debuggers (GDB and GDB/MI).
c) The changes worked enough and I have wired up enough so that when I run a program to debug it in the C::B GUI the connection through the debugger_WXDAP.dll works and I get debug output on the lldb-vscode.exe. I have only wired up the connection and the events only log to the debug log on the C:B gui.

There is still a huge amount of work to do and it will take a while to go from where I am to

If I find anything I will create issues and/or PR's against the github repo.

Thanks very much for your help and advice on the DAP and the DLL.

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3352
Re: LLDB debugger low level interface investigation results
« Reply #12 on: June 25, 2022, 12:53:12 am »
Hi!
this looks really nice, great work.
Also thank you for sharing here in the forum!



Offline AndrewCot

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 678
Re: LLDB debugger low level interface investigation results
« Reply #13 on: June 26, 2022, 02:42:47 am »
I now have some rudimentary debugging on an exe in C::B working as follows:
  • The exe is loaded via the DAP dll using the new DAP debugger plugin.
  • The exe can be started and run with a breakpoint set on main() as default in the debugger plugin for the time being (I do not have any persistent breakpoint or watches etc)
  • I can use step to the next line. I have wired up most of the other step features, but have not tested them.
  • I can set one line break point in the file and then run to the break point. The DAP break point API works on a file basis with array of breakpoints for the file, which is different to the GDB/MI code I started with and as such I need to refactor the way the breakpoints are stored in the debugger plugin.
  • I have the call stack partially working in that it shows data and some of it looks right, but some does not.
  • I can stop debugging and start debugging again.
Things not in the list above are not working. 


I will be working on the following in the order listed, unless I hit something or need a break on the work:
  • Add support for multiple line break points in a file
  • Wire up simple watches. Aka add to watch dialog only and update as you step / run the debugee
  • Enable break point and watchs to be persistent from the GDB/MI debugger plugin.
  • Get the call stack working correctly
  • Wire up starting the LLDB debugger exe when you start debugging. (commented out at the moment so I can see what is happening on a command prompt)
  • Migrate/test on Linux
  • Migrate/test on MacOS
  • Use in anger to fix C::B issue(s) on MacOS. In other words use it in the real world.
  • Add features required to make debugging better.
  • Update ticket 1114 to add support for the CLANG compiler to detect debugger and add it as a debugger automatically.
« Last Edit: June 26, 2022, 03:10:19 am by AndrewCot »

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2808
Re: LLDB debugger low level interface investigation results
« Reply #14 on: June 26, 2022, 07:25:02 am »
Wow!! It nice to see this happening.