Avba
Avba

Reputation: 15266

Xcode -How to interact with lldb address and send messages

I am debugging my app in lldb and need to send messages to objects. I don't have the object variable name (i.e. self.object) rather an address to that object. So for instance I have a UIGestureRecognizer which variable I don't have access to and has an address like:

0x7fe110297360

I want to send it a message that works with gesture recogniser:

[gestureA requireGestureToFail:gestureB];

So I translate that to a few variations - each unsuccessful:

expr [0x7fe110297360 requireGestureToFail:0x7fe10e842c00]
expr (long)[((id)0x7fe110297360) requireGestureToFail:((id)0x7fe10e842c00)]
expr -- [0x7fe110297360 requireGestureToFail:0x7fe10e842c00]
expr -- (long)[((id)0x7fe110297360) requireGestureToFail:((id)0x7fe10e842c00)]
expr [((id)0x7fe110297360) requireGestureToFail:((id)0x7fe10e842c00)]

each is acknowledged with an error:

error: warning: receiver type 'long' is not 'id' or interface pointer, consider casting it to 'id'
error: no known method '-requireGestureToFail:'; cast the message send to the method's return type
error: 1 errors parsing expression




(lldb) expr [((id)0x7fe110297360) requireGestureToFail:((id)0x7fe10e842c00)]
error: no known method '-requireGestureToFail:'; cast the message send to the method's return type
error: 1 errors parsing expression

Upvotes: 2

Views: 1930

Answers (1)

maciejs
maciejs

Reputation: 358

Then, why don't you cast it to a proper type instead?

exp -- [(UIGestureRecognizer *)address1 requireGestureToFail:(UIGestureRecognizer *)address2];

If you'd like to play a little more and call this method by it's address (assuming you still know all the types), here's an example.

Given the following code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    [self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
    [[self window] setBackgroundColor:[UIColor purpleColor]];

    UIGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(windowTapped:)];
    [[self window] addGestureRecognizer:gr];
    [[self window] makeKeyAndVisible];
    return YES;
}

and setting a brakpoint right after adding the gesture recognizer to the window, here's what you can do:

(lldb) po [self window]
<UIWindow: 0x7ffd2acaff50; frame = (0 0; 320 480); hidden = YES; gestureRecognizers = <NSArray: 0x7ffd2acb6930>; layer = <UIWindowLayer: 0x7ffd2aca8ac0>>

(lldb) image lookup -v -r -n "-\[UIGestureRecognizer view\]"
1 match found in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/UIKit.framework/UIKit:
        Address: UIKit[0x00000000003c5c03] (UIKit.__TEXT.__text + 3946627)
        Summary: UIKit`-[UIGestureRecognizer view]`
         Module: file = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/UIKit.framework/UIKit", arch = "x86_64"
         Symbol: id = {0x000050db}, range = [0x0000000107ee4c03-0x0000000107ee4c14), name="-[UIGestureRecognizer view]"

(lldb) exp UIView *(*$m)(id, SEL) = (UIView *(*)(id, SEL))0x0000000107ee4c03
(lldb) exp SEL $s = @selector(view)
(lldb) p gr
(UIGestureRecognizer *) $1 = 0x00007ffd2ad38c90
(lldb) exp -- $m((id)0x00007ffd2ad38c90, $s)
(UIView *) $2 = 0x00007ffd2acaff50
(lldb) po $2
<UIWindow: 0x7ffd2acaff50; frame = (0 0; 320 480); hidden = YES; gestureRecognizers = <NSArray: 0x7ffd2acb6930>; layer = <UIWindowLayer: 0x7ffd2aca8ac0>>

(lldb) 

Basically what you do is, find the address of the method in memory (image lookup command, -v switch), create a temporary debugger variable (i.e $m here) of a proper type, and then using the 2 hidden arguments that you have to pass to each ObjC method call, call this method. As you can see comparing the addresses, you're getting the original window back as intended. Hope that helps.

Upvotes: 2

Related Questions