Macos OSX等效于SymGetLineFromAddr或SymGetLineFromAddr64

Macos OSX等效于SymGetLineFromAddr或SymGetLineFromAddr64,macos,backtrace,mach-o,dyld,dwarf,Macos,Backtrace,Mach O,Dyld,Dwarf,我想将源文件和行号添加到我的回溯中,在Windows上有一个很好的函数SymGetLineFromAddr64,它提供了此类信息(如果可用)。我在mac上找不到类似的东西。 dladdr只输出符号名而不输出文件信息。在OS X上没有与SymGetLineFromAddr64等效的公共名称,但您可以使用开发工具获取源文件和行号 下面是一些获得完全符号化回溯的示例代码 #导入 静态NSArray*回溯(NSArray*callStackReturnAddresses) { NSMUTABLEARRY

我想将源文件和行号添加到我的回溯中,在Windows上有一个很好的函数SymGetLineFromAddr64,它提供了此类信息(如果可用)。我在mac上找不到类似的东西。
dladdr只输出符号名而不输出文件信息。

在OS X上没有与
SymGetLineFromAddr64
等效的公共名称,但您可以使用开发工具获取源文件和行号

下面是一些获得完全符号化回溯的示例代码

#导入
静态NSArray*回溯(NSArray*callStackReturnAddresses)
{
NSMUTABLEARRY*回溯=[NSMUTABLEARRY new];
for(CallStackReturnAddresss中的NSNumber*地址)
{
NSString*hexadecimalAddress=[NSString stringWithFormat:@“0x%0*lx”,(int)sizeof(void*)*2,address.unsignedIntegerValue];
NSTask*任务=[NSTask new];
NSPipe*管道=[NSPipe pipe];
task.launchPath=@“/usr/bin/xcrun”;
task.arguments=@[@“atos”、@“-d”、@“-p”、@(getpid()).description,hexadecimalAddress];
task.standardOutput=管道;
NSString*符号=@“?”;
@试一试
{
[任务启动];
NSData*data=[pipe.fileHandleForReading readDataToEndOfFile];
symbol=[[NSString alloc]initWithData:数据编码:NSASCIIStringEncoding];
symbol=[symbol stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
[task waitUntilExit];
}
@捕获(NSException*异常){}
[回溯添加对象:[NSString stringWithFormat:@“%@%@”,十六进制地址,符号]];
}
返回[回溯副本];
}
静态孔隙试验(孔隙)
{
NSLog(@“%@”,回溯([NSThread callStackReturnAddresses]);
}
int main(int argc,const char*argv[]
{
test();
返回0;
}
运行此代码将产生以下输出:

0x000000010000134e test (in a.out) (main.m:31)
0x000000010000131b main (in a.out) (main.m:36)
0x00007fff8c0935fd start (in libdyld.dylib) + 1

请注意,
atos
(和
xcrun
)未安装在非开发人员系统上,因此这在已部署的应用程序中不起作用。另一个选项是
backtrace\u symbols()
实际上,这只适用于安装了开发人员工具的系统。如果你真的需要源文件名+行号信息,你必须使用私有框架或编写你自己的DWARF解析器。根据我读到的关于CoreSymaration的内容,这正是我需要的。我试试看。我不想写我自己的DWARF解析器,DWARF看起来很吓人。嗯,
atos
只是一些CoreSymaration函数的简单CLI包装。与其处理私有框架,不如将
atos
二进制文件捆绑到应用程序中。此外,如果需要对崩溃报告进行符号化,则应查看
符号‌icatecrash
二进制文件,来自Xcode的DTDeviceKitBase框架。处理私有框架听起来并不可怕。我只是将其设置为可选,以便在那里更改某些内容(如删除)时,我的回溯将不包含源文件/行号信息。