ios - Xcode - 如何与 lldb 地址交互并发送消息

标签 ios xcode debugging lldb

我正在 lldb 中调试我的应用程序,需要向对象发送消息。 我没有对象变量名称(即 self.object),而是该对象的地址。 例如,我有一个 UIGestureRecognizer ,我无权访问该变量,并且其地址如下:

0x7fe110297360

我想向它发送一条与手势识别器配合使用的消息:

[gestureA requireGestureToFail:gestureB];

所以我将其翻译成一些变体 - 每个变体都不成功:

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)]

每个都被确认但有错误:

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

最佳答案

那么,为什么不将其转换为正确的类型呢?

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

如果您想多玩一点并通过其地址调用此方法(假设您仍然知道所有类型),这里有一个示例。

给出以下代码:

- (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;
}

并在将手势识别器添加到窗口后立即设置断点,您可以执行以下操作:

(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) 

基本上你要做的是,找到内存中方法的地址(图像查找命令,-v开关),创建一个适当类型的临时调试器变量(即这里的$m),然后使用2个隐藏参数您必须传递给每个 ObjC 方法调用,调用此方法。正如您所看到的,比较地址,您将按预期恢复原始窗口。 希望有帮助。

关于ios - Xcode - 如何与 lldb 地址交互并发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27293454/

相关文章:

ios - 使用 firebase 获取 UITableview 中的父键

ios - 导航栏背景颜色

ios - Xcode 11.2.1 错误 - Swift 5.1.2 编译器无法导入使用 Swift 5.1 编译的模块

iOS/iPhone 应用程序似乎为我的文本添加了颜色 mask /颜色阴影

android - 如何调试连接到 Facebook SDK 的 Android 应用程序?

ios - 我应该将 iOS 下载保存在哪个目录中?

iOS swift : Tableview data disappear when i scroll it

arrays - 在 Init 函数中发出异步 Web 请求 [Swift]

android - 使用 WebView/GapDebug 调试 PhoneGap 应用程序

Android 跟踪文件描述符在生产环境中泄漏