LLDB wrapper mainly written in Objective-C++ and complemented in Swift.
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
LLDB.framework
LLDBWrapper.xcodeproj
LLDBWrapper
SampleProgram3
SampleProgram4
TestdriveApp
Workbench1
Workbench2
.gitignore
README.md
liblldb-core-hack.a

README.md

Eonil/LLDBWrapper

Hoon H.

2014/09/07 2015/02/01 2015/08/20

This is a wrapper of LLDB's public C++ API. Wrapped in Objective-C++, and complemented in Swift. Intended to be used in Swift.

Named as LLDBWrapper to avoid possible name conflict with any existing system LLDB stuffs. (I mean Xcode version)

Getting Started

First, select and run "TestdriveApp" target to verify correct program execution. A debugger will start up and launch predefined test program target. ("SampleProgram3") Press Command+R to perform "step-over". If you see stack frame changes with some print output, it's working.

Now see the source code of "TestdriveApp" to see how to use this framework.

Requirements

  • Swift 3.0.

Caution

  • You have to add $(SYSTEM_APPS_DIR)/Xcode.app/Contents/SharedFrameworks to LD_RUNPATH_SEARCH_PATHS in build settings of your build target.

  • Do not embed included LLDB.framework in your product. See below for details.

Though this framework originally intended to work with open-sourced LLDB build, but there were two problems.

  • Building of LLDB takes too long and needs some unfamiliar works. You are very likely to have several build issues. (such as code signing)

  • Built binary is very large. It usually takes hundred megabytes. Then it also cannot be included in Git repository. (Github allows only files up to about 100MiB)

To avoid these problems, this project currently contains a "fake" prebuilt LLDB.framework that just symlinked to binaries of LLDB.framework shipped within Xcode. Anyway this fake framework is required to expose header files to build process.

This means this library will dynamically link to Xcode's LLDB component at runtime, and you may have some troubles by Xcode versions or another C++ binary code interfacing issues.

If you want, you can link to your own build of LLDB by changing link settings. (such as LD_RUNPATH_SEARCH_PATHS) Linking to Xcode component is just current decision, and can be changed later.

Currently, enum constant values are explicitly designated. These values are generated by Clang library so should be correct. But I think this is not truly reliable because original enums does not define specific value, and that means it must be treated as symbols rather than numbers to be reliable. I will change this later to use name-based mapping.

This does not fully cover all API. Only covers what I need. For example, this fully lacks asynchronous event notification part. Anyway such features can be added later if I feel need for it.

Lessons from Trials

I have tried SWIG-like C API generation from C++ source code, but I realised it requires too much work and Swift compiler is not stable enough yet. I don't have such time. DO NOT TRY THIS AT HOME EVER AGAIN unless you have enough idle time. (I wasted about 3 weeks and finally abandoned the approach --- failure)

Wrapping Design Choices

  • Invalid objects will also be wrapped and returned. No nil will be returned regardless of IsValid state. Anyway, it doesn't mean you can use them freely. Calling methods on invalid objects care not expected to work properly.

    This is because;

    • LLDB seems treating invalid state as a part of regular state.
    • many objects in invalid state (where IsValid == false) still provides useful informations.
    • any existing valid object can become invalid anytime.
  • Equality and comparison operators can be provided if original C++ classes provide corresponding operators.

  • Identity of Objective-C object has no meaning. Do not rely on it. Generally, there's no generic identity check. Anyway some equality check provides identity check case by case.

  • Use C numeric types as is as much as possible in core API. Convert them in Swift-side extensions where needed. If the numeric type is typedefed inside of C++ namespaces/classes, then make a new C typedef manually, and static_assert for type matching.

  • Strings will always be passed by copying into a new NSString by default. Raw C-string pointers will not be exposed unless required.

  • Enums should be redefined in C side, and mapped to corresponding C++ constants.

    • Current implementation is not following this rule. It is because I couldn't decide yet what to do for bit-field values.
  • No exception. (1) Swift has no exception facility. (2) I don't think exceptions are great good. Wrapper method must return a proper error or crash reliably.

Further Readings

License

This project is licensed under "MIT License". That is limited only to my works. This project contains files from LLVM/LLDB projects that are licensed under "University of Illinois/NCSA Open Source License". Product of this project will be dynamically linked to some components of Xcode if there is one exists at runtime. I DO NOT redistribute those components. So I don't think this linkage would cause any license issue, but anyway, I am not a laywer. If you think something is wrong, please let me know. Thanks.