Linking the lldb C++API/library with other projects

Does anyone have pointers on how to link the lldb C++ API/library with another project that uses a command line driven build system?

We would like to incorporate the lldb C++ API/library into our Common Lisp programming environment to get better backtraces and debug info in a portable way (OS X and Linux).

lldb is written as a library and in principle this should be possible.
In practice I’ve had a tough time getting started. I can build lldb with Xcode on OS X.
This is not a criticism - I know resources are limited. The documentation for using the C++ API of lldb are thin and examples are few to non-existent.
I don’t need a lot of help - I would just like a starting point.
I’m developing CANDO, an implementation of Common Lisp that uses llvm as a backend (github.com/drmeister/cando)
I have extensive experience using the llvm/clang API’s within CANDO.

Best,

Christian Schafmeister, Professor
Chemistry Department
Temple University

Does anyone have pointers on how to link the lldb C++ API/library with another project that uses a command line driven build system?

You can always use "xcodebuild" if you need to for Mac builds:

lldb:
    cd /tmp/lldb
    xcodebuild -configuration Release

For all others cmake + ninja is the preferred method. Mac builds don't use cmake + Ninja as we let Xcode make the LLDB.framework. A framework is a directory that contains both the shared library and all public header files needed in order for people to link against the LLDB shared library. It is possible to build LLDB using cmake + ninja on Mac, but you end up with a lldb.dylib shared library instead of a LLDB.framework. The nice thing about the LLDB.framework being a directory is that it gives us a place to put all of the support binaries that go along with LLDB: lldb-server, darwin-debug (mac only), lldb-argdumper, header files needed by clang for expression parsing, python modules, and more.

You can see all that is in the framework by doing:

$ find /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework -type f
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/_CodeSignature/CodeResources
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/__clang_cuda_cmath.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/__clang_cuda_intrinsics.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/__clang_cuda_math_forward_declares.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/__clang_cuda_runtime_wrapper.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/__stddef_max_align_t.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/__wmmintrin_aes.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/__wmmintrin_pclmul.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/adxintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/altivec.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/ammintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/arm_acle.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/arm_neon.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/armintr.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx2intrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512bwintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512cdintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512dqintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512erintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512fintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512ifmaintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512ifmavlintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512pfintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512vbmiintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512vbmivlintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512vlbwintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512vlcdintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512vldqintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avx512vlintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/avxintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/bmi2intrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/bmiintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/clflushoptintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/cpuid.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/cuda_builtin_vars.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/emmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/f16cintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/float.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/fma4intrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/fmaintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/fxsrintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/htmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/htmxlintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/ia32intrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/immintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/intrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/inttypes.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/iso646.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/limits.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/lzcntintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/mm3dnow.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/mm_malloc.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/mmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/module.modulemap
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/mwaitxintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/nmmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/opencl-c.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/pkuintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/pmmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/popcntintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/prfchwintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/rdseedintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/rtmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/s390intrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/shaintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/smmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/stdalign.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/stdarg.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/stdatomic.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/stdbool.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/stddef.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/stdint.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/stdnoreturn.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/tbmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/tgmath.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/tmmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/unwind.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/vadefs.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/varargs.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/vecintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/wmmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/x86intrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/xmmintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/xopintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/xsavecintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/xsaveintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/xsaveoptintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/xsavesintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Clang/include/xtestintrin.h
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/darwin-debug
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/debugserver
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Info.plist
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/lldb-argdumper
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/lldb-server
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/__init__.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/diagnose/__init__.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/diagnose/diagnose_nsstring.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/diagnose/diagnose_unwind.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/embedded_interpreter.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/formatters/__init__.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/formatters/attrib_fromdict.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/formatters/cache.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/formatters/cpp/__init__.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/formatters/cpp/gnu_libstdcpp.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/formatters/cpp/libcxx.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/formatters/Logger.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/formatters/metrics.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/formatters/synth.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/macosx/__init__.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/macosx/crashlog.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/macosx/heap/heap_find.cpp
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/macosx/heap/Makefile
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/macosx/heap.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/runtime/__init__.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/utils/__init__.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/lldb/utils/symbolication.py
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/repl_swift
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/version.plist
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/XPCServices/RootDebuggingXPCService.xpc/Contents/_CodeSignature/CodeResources
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/XPCServices/RootDebuggingXPCService.xpc/Contents/Info.plist
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/XPCServices/RootDebuggingXPCService.xpc/Contents/MacOS/RootDebuggingXPCService
/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/XPCServices/RootDebuggingXPCService.xpc/Contents/version.plist

We would like to incorporate the lldb C++ API/library into our Common Lisp programming environment to get better backtraces and debug info in a portable way (OS X and Linux).

lldb is written as a library and in principle this should be possible.
In practice I’ve had a tough time getting started. I can build lldb with Xcode on OS X.
This is not a criticism - I know resources are limited. The documentation for using the C++ API of lldb are thin and examples are few to non-existent.
I don’t need a lot of help - I would just like a starting point.

To start with I would recommend:
1 - build with Xcode on Mac and link against the LLDB.framework
2 - build with cmake + ninja on all other systems and link against the liblldb.so. Then you will need to package lldb, liblldb.so and all needed extra files (lldb-* from the build directory, the python modules, etc) in a place that LLDB can find them (usually all executables in the same directory, python module in the same directory as liblldb.so (please correct me if I am wrong on this linux folks!)

I’m developing CANDO, an implementation of Common Lisp that uses llvm as a backend (github.com/drmeister/cando)
I have extensive experience using the llvm/clang API’s within CANDO.

That is good, then you will already understand the make + ninja output build directory that will contain lldb and liblldb.so for other systems.

Once you have linked against the LLDB.framework or liblldb.so, then you need to call the following static class function:

using namespace lldb;
SBDebugger::Initialize();

before calling anything else. This is the call that initializes all LLDB plug-ins and gets everything ready for more. One things are initialized you will want to create a lldb::SBDebugger object using:

bool source_init_files = true;
SBDebugger debugger = SBDebugger::Create(source_init_files);

The debugger object is what owns the command line interpreter (the "(lldb)" prompt) and all targets.

If you are going to want people to use a command line interface to lldb, create a FILE for stdin/out/err and pass them to the debugger:

bool transfer_ownership = false;
debugger.SetInputFileHandle(stdin, transfer_ownership);
debugger.SetOutputFileHandle(stdout, bool transfer_ownership);
debugger.SetErrorFileHandle(stderr, bool transfer_ownership);

It doesn't sound like you need the command line interpreter for backtraces, but I mention it just in case. If you do plan on using it, let us know.

Now you can create and use targets by creating a lldb::SBTarget object using the "debugger" instance you have.

Note that LLDB can't be used to backtrace itself, so if you are looking to backtrace things in your current process you should probably use other APIs.

Let us know if you have any questions.

Greg Clayton

Dear Greg,

Thank you very much for your detailed and thoughtful response.

A couple of followup questions based on what you said:

(1) You say: "since LLDB can't be used to backtrace itself…"
Do I (a) need to fork another process and call the LLDB API’s to get backtraces for the original process or (b) can I simply create another thread and call LLDB API’s to interogate other threads using the SBThread API? Or can I do both of these?

(2) When you say "so if you are looking to backtrace things in your current process you should probably use other APIs.”
By "other APIs” do you mean other SBxxxx class API’s like SBThread? or do you mean other API’s entirely? If the latter could you give an example?

(3) If I call LLDB from my code like this - how would you recommend distributing this?

(a) When building from source should I have the build system pull lldb from a the llvm github repo?
(b) Can I ship the lldb framework on OS X and lldblib.so (LInux) with my binary release?
(c) On OS X - can I use the builtin lldb library? I haven’t checked if header files are available.
(d) On Linux - can I use package manager installed versions of lldb?

For some of these I realize that I'll have to do some legwork to figure out what is available from package managers etc.

(4) Since I have to debug from a separate process does the following sound reasonable.
(i) My program detects an error and enters into its debugger.
(ii) It forks a debugging process and that interacts with the user who uses it to debug the main process.
(iii) The debugger process shuts down and the main process continues.

I’d be doing this from within a Common Lisp programming environment called SLIME in Emacs - I have no idea right now if it’s possible to have the integrated debugger in SLIME work with a separate debugging process. Fun, fun, fun.

Thank you!

.Chris.

Dear Greg,

Thank you very much for your detailed and thoughtful response.

A couple of followup questions based on what you said:

(1) You say: “since LLDB can’t be used to backtrace itself…”
Do I (a) need to fork another process and call the LLDB API’s to get backtraces for the original process or (b) can I simply create another thread and call LLDB API’s to interogate other threads using the SBThread API? Or can I do both of these?

You can do the first, not the second. LLDB attaches to processes via ptrace which means it will suspend all threads in the process it is attaching to, so you can’t do this to yourself. Forking another process will do the trick. You can also do all of this from Python! The entire LLDB API is exposed to python and python can be used on the command line from a python script, or from within LLDB itself by using the “script” command which drops you into an embedded python interpreter. On Mac, if you know Xcode is installed, you can just run a python script to do what you need. Let me know if this sounds interesting. On linux, you could use the installed lldb to do the backtraces using a python script as well.

(2) When you say "so if you are looking to backtrace things in your current process you should probably use other APIs.”
By "other APIs” do you mean other SBxxxx class API’s like SBThread? or do you mean other API’s entirely? If the latter could you give an example?

Other APIs not in LLDB if you must stay in process:

$ man backtrace

If you launch another process, it will be able to backtrace your current process and you can use LLDB’s APIs.

(3) If I call LLDB from my code like this - how would you recommend distributing this?

(a) When building from source should I have the build system pull lldb from a the llvm github repo?

You might think about locking onto they latest public release of lldb. This might be more stable than just grabbing top of tree.

(b) Can I ship the lldb framework on OS X and lldblib.so (LInux) with my binary release?

Yes. You might think about using python and just using the installed LLDB?

(c) On OS X - can I use the builtin lldb library? I haven’t checked if header files are available.

Header files are not available, but our API is stable. You could theoretically link against the top of tree LLDB.framework and tell it to use the system version (in /Applications/Xcode.app/Contents/SharedFrameworks, or somewhere for linux)

(d) On Linux - can I use package manager installed versions of lldb?

Yes. If you go this route, I would suggest using a python script. Then you don’t even need to link against lldb!

For some of these I realize that I’ll have to do some legwork to figure out what is available from package managers etc.

(4) Since I have to debug from a separate process does the following sound reasonable.
(i) My program detects an error and enters into its debugger.
(ii) It forks a debugging process and that interacts with the user who uses it to debug the main process.
(iii) The debugger process shuts down and the main process continues.

I’d be doing this from within a Common Lisp programming environment called SLIME in Emacs - I have no idea right now if it’s possible to have the integrated debugger in SLIME work with a separate debugging process. Fun, fun, fun.

That sounds like it can work. If you want to actually use the debugger when there is an issue, you will not want to use python. But if you are just trying to get backtraces, then a python script might work, plus it will insulate you from having to link against lldb.

Thank you!

No worries, we are here to help!

Let me know what you think about my above comments,

Greg Clayton

Greg,

We are developing a compiler for Common Lisp that uses LLVM as the backend and interoperates with C++ - it has its own REPL and built in compiler.
Our compiler generates llvm-ir that we link directly with llvm-ir generated from the C++ code using LTO.
I’ve exposed much of the LLVM C++ API and Clang ASTMatcher C++ API for automatic analysis and refactoring of our C++ code.

The Python API’s are not that useful to us.
Although - maybe launching lldb as a separate process to get the backtrace with a python script may be a reasonable thing to do - if that’s all that I want to do.
I’d also like to explore accessing lexical variables and setting breakpoints and watchpoints using the C++ API.
The C++ API’s - they are much more straightforward to work with for us.

I am already using ‘backtrace’ - but I don’t get function arguments with that sadly.

Best,

.Chris.

For catching runtime errors on Linux you should just SEGV and system crash
reporter will catch it, backtrace it, bugreport it etc. At least ABRT in
Fedora/RHEL case, other distros have some similar tools for that.

And developers should run the program under debugger in the first place.

Jan

lldb-mi, in /tools/lldb-mi , loads the shared library and uses the SB APIs. That might be a good start for you. main() is in MIDriverMain.cpp.

You might think about integrating your REPL directly into LLDB? That is how we did it with Swift. Then you get everything for free:
- debug your REPL code by setting breakpoints
- when a REPL code snippet crashes, see the backtrace!

You might search for a Swift REPL demo and see what you think.

Below is an example of the Swift REPL that is built into LLDB:

$ swift
Welcome to Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42). Type :help for assistance.
  1> func foo() -> Int {
  2. return 12;
  3. }
  4.
  4> foo()
$R0: Int = 12

Any line that starts with ':' is a LLDB command. Below we set a breakpoint on line 2 of our REPL code:

  5> :b 2
Breakpoint 1: where = $__lldb_expr3`__lldb_expr_2.foo () -> Swift.Int + 4 at repl.swift:2, address = 0x00000001000c5014

Now we can call foo() and hit our breakpoint:

  5> foo()
Execution stopped at breakpoint. Enter LLDB commands to investigate (type help for assistance.)
Process 40238 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x00000001000c5014 $__lldb_expr3`foo() -> Int at repl.swift:2
   1 func foo() -> Int {
-> 2 return 12;
   3 }
   4 foo()
   5 foo()

Note we drop into the LLDB command prompt. We can view variables, backtrace, etc. Here we just continue:

(lldb) c
Process 40238 resuming

Now we are back in the REPL:

  6> func bar() -> Int {
  7. return foo() + 23;
  8. }
  9> bar()

We are going to call "bar()" which will call "foo()" so we will hit the breakpoint again...

Execution stopped at breakpoint. Enter LLDB commands to investigate (type help for assistance.)
Process 40238 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x00000001000c5014 $__lldb_expr3`foo() -> Int at repl.swift:2
   1 func foo() -> Int {
-> 2 return 12;
   3 }
   4 foo()
   5 foo()
   6 func bar() -> Int {
   7 return foo() + 23;
(lldb) c
Process 40238 resuming
10>

By the way: "swift" ends up executing:

/Applications/Xcode.app/Contents/Developer/usr/bin/lldb --repl=-enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -color-diagnostics

Common Lisp is a different kind of language - it’s never supposed to seg fault. :slight_smile:

It’s a dynamic language that I am compiling to llvm-ir and using to call and drive C++ libraries.
The integrated debugger takes over when an error is signaled and it should allow the user to view the stack, inspect arguments and lexical variables and to unwind the stack and proceed indefinitely.

Now, I’m generating llvm-ir and that runs just like C++ generated llvm-ir.
My stack traces are C++ style stack traces with stack frames from C++ functions interleaved with stack frames from Common Lisp code.
I use C++ exception handling to unwind the stack in Common Lisp and that enables RAII to keep working.

I’m kind of caught between worlds. I already have a debugger that can view stack traces - but to achieve it I’ve had to insert calls at the entry and exit of all Common Lisp functions to spill register arguments and to maintain a shadow stack of stack frames for Common Lisp functions. This is a huge barrier to inlining and optimization. I also generate DWARF metadata but I can’t access it without going through lldb.
That’s why I’d like to incorporate the lldb C++ API’s.

Best,

.Chris.

So "error is signaled" is like an assert()? assert() generates SIGABRT so
that system crash reporter will catch it, backtrace it, bugreport it etc.

Or a debugger will catch it the same way if developer has run it.

Jan

I’ve pondered integrating the REPL into LLDB - but what I really want/need is for all of this to run within SLIME - and I don’t know enough about it to do that.
I do know how to talk to complex C++ API’s from Common Lisp - hence my line of questioning.

I’ll think on that more though. What you describe might be appropriate for an interactive development mode. Thank you.

Common Lisp users have certain expectations that they will get backtraces with arguments and be able to interactively inspect arguments and lexical variables using the interactive SLIME Debugger interface in Emacs. The more I use that interface - the more I fall in love with it.
I’m trying to figure out where the best compromise is.

Best,

.Chris.