When you come across <__NSXXXBlock__: 0xrandomnumber> while debugging a block in LLDB, how to locate the block


#1

I don’t know what’s under the hood at the moment, please just follow the example below. If you’re curious, figure it out yourself and post a topic explaining the principles, thanks.

(lldb) po $x5
<__NSStackBlock__: 0x16fd26ac8>

(lldb) memory read --size 8 --format x 0x16fd26ac8
0x16fd26ac8: 0x00000001a0d11558 0x00000000c2000000
0x16fd26ad8: 0x00000001022d4638 0x00000001037ab4f0
0x16fd26ae8: 0x0000000126f4a1c0 0x0000000126ac9ae0
0x16fd26af8: 0x00000001821e7f00 0x0000000124d31400

Note, for arm64, the 2nd command is memory read --size 8, while for armv7/armv7s it should be memory read --size 4.

The value you get from 0x00000001022d4638 - ASLR offset is the address of the block. Go to this address in IDA or hopper then you’ll see the block implementation.


如何知道block的参数类型和返回值类型?
一个dispatch_after 的block 问题求助
请问,UIAlertController的AlertAction该怎么下断点?
ReactiveCocoa 如何调试?
知道__NSMallocBlock__的地址,如何查看具体的内容?
#2

太感谢了!自己苦想一天都没什么头绪,这样一下就找到了,谢谢楼主!


#3

根据Block的结构体,函数指针是void (*invoke)(void *, …); 所以楼主选了17个字节(也即第3个16Byte)的那个:

struct Block_literal_1 {
void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
int flags;
int reserved;
void (*invoke)(void *, ...);
struct Block_descriptor_1 {
unsigned long int reserved;         // NULL
    unsigned long int size;         // sizeof(struct Block_literal_1)
    // optional helper functions
    void (*copy_helper)(void *dst, void *src);     // IFF (1<<25)
    void (*dispose_helper)(void *src);             // IFF (1<<25)
    // required ABI.2010.3.16
    const char *signature;                         // IFF (1<<30)
} *descriptor;
// imported variables
};