LLDB如何导入符号以访问结构体定义?
解决LLDB调试中无法识别sockaddr结构体的问题
场景还原
调试应用时,在SCNetworkReachabilityCreateWithAddress的stub处下了断点:
imp___stubs__SCNetworkReachabilityCreateWithAddress: jmp qword [_SCNetworkReachabilityCreateWithAddress_10000c0c8]
此时$rdi寄存器存储了要检查的sockaddr结构体地址,尝试用以下命令查看内容,但LLDB无法识别该结构体类型:
expr *((sockaddr *)$rsi) expr *((sockaddr_in *)$rsi) p *((sockaddr *)$rsi) p *((sockaddr_in *)$rsi)
手动定义结构体后:
expr struct $sockaddr { unsigned char sa_len; unsigned char sa_family; char sa_data[14]; }
执行expr ($sockaddr)$rdi时触发错误:
candidate constructor (the implicit copy constructor) not viable: no known conversion from 'unsigned long' to 'const $sockaddr' for 1st argument candidate constructor (the implicit move constructor) not viable: no known conversion from 'unsigned long' to '$sockaddr' for 1st argument candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
解决方案
方案1:导入系统头文件让LLDB识别原生结构体
sockaddr定义在<sys/socket.h>中,在LLDB中执行以下命令导入头文件,就能直接使用系统原生的结构体类型:
expr -l objc++ -O -- #include <sys/socket.h>
之后就可以正常执行查看命令:
p *(sockaddr*)$rdi p *(sockaddr_in*)$rdi
方案2:修正手动定义结构体后的转换方式
手动定义结构体后,$rdi是结构体的内存地址,不能直接转成结构体实例,需要先转成指针再解引用:
// 先定义结构体 expr struct $sockaddr { unsigned char sa_len; unsigned char sa_family; char sa_data[14]; } // 正确的查看命令 expr *(($sockaddr*)$rdi)
这样就能正确解析寄存器中存储的结构体内容了。
内容的提问来源于stack exchange,提问作者IRP_HANDLER
相关产品推荐
相关产品推荐

