Search code examples
objective-clldb

Create a class using Objective-C in the lldb expression context


I am trying to declare and instantiate a class using Objective-C in the lldb expression context. I launch an executable and attach to it via the lldb. Once the executable stops I execute the expression.

(lldb) e -l objc --
Enter expressions, then terminate with an empty line to evaluate:
  1: @import Foundation; 
  2: @implementation MyClass : NSObject 
  3: - (void)foo { 
  4:     NSLog(@"bar"); 
  5: } 
  6: @end 
  7: [[MyClass new] foo]; 
error: <user expression 15>:2:1: unexpected '@' in program
@implementation MyClass : NSObject
^

The equivalent expression in Swift seems to work just fine.

(lldb) e -l swift -- 
Enter expressions, then terminate with an empty line to evaluate:
  1: class MyClass { 
  2: func foo { print("bar") } 
  3: } 
  4: MyClass().foo() 
  5:  

bar

I am using lldb-1103.0.22.10 which comes with Xcode 11.7 toolchain.

Is it possible to declare and instantiate a class using Objective-C in the lldb expression?


Solution

  • It should be (I've never tried so I can't say for certain) but it would take some more work. The problem is that you have to get your new class registered with the ObjC runtime. In the most common case, the work of registering a class with the ObjC runtime is done by the dynamic loader when the dylib or executable containing the class implementation is loaded. Since lldb expressions aren't dylibs (wrapping them that way would be too heavy-weight) this isn't getting done for your new class.

    However, there are functions in the objc runtime that allow you to add classes on the fly. You could use them to register your new class. There's some info about these functions on the ObjC Runtime info pages:

    https://developer.apple.com/documentation/objectivec/objective-c_runtime

    lldb's expression parser could scan the result of the expression for new ObjC classes and register them by hand for you. It doesn't do that at present. You could file a enhancement request with http://bugs.llvm.org and see if anybody is interested in adding this capability. It is a bit esoteric, however.

    The Swift runtime works differently from the ObjC runtime and doesn't need this extra bit of work.