【问题标题】:OSX equivalent of SymGetLineFromAddr or SymGetLineFromAddr64OSX 等效于 SymGetLineFromAddr 或 SymGetLineFromAddr64
【发布时间】:2015-03-24 10:51:21
【问题描述】:

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

【问题讨论】:

    标签: macos backtrace mach-o dyld dwarf


    【解决方案1】:

    在 OS X 上没有与 SymGetLineFromAddr64 等效的公共等价物,但您可以使用 atos(1) 开发人员工具获取源文件和行号。

    这里是一些示例代码,用于获得完全符号化的回溯。

    #import <Foundation/Foundation.h>
    
    static NSArray * Backtrace(NSArray *callStackReturnAddresses)
    {
        NSMutableArray *backtrace = [NSMutableArray new];
        for (NSNumber *address in callStackReturnAddresses)
        {
            NSString *hexadecimalAddress = [NSString stringWithFormat:@"0x%0*lx", (int)sizeof(void*) * 2, address.unsignedIntegerValue];
            NSTask *task = [NSTask new];
            NSPipe *pipe = [NSPipe pipe];
            task.launchPath = @"/usr/bin/xcrun";
            task.arguments = @[ @"atos", @"-d", @"-p", @(getpid()).description, hexadecimalAddress ];
            task.standardOutput = pipe;
            NSString *symbol = @"???";
            @try
            {
                [task launch];
                NSData *data = [pipe.fileHandleForReading readDataToEndOfFile];
                symbol = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
                symbol = [symbol stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
                [task waitUntilExit];
            }
            @catch (NSException *exception) {}
            [backtrace addObject:[NSString stringWithFormat:@"%@ %@", hexadecimalAddress, symbol]];
        }
        return [backtrace copy];
    }
    
    static void test(void)
    {
        NSLog(@"%@", Backtrace([NSThread callStackReturnAddresses]));
    }
    
    int main(int argc, const char * argv[])
    {
        test();
        return 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_symbols()
    • 确实,这仅适用于安装了开发人员工具的系统。如果你真的需要源文件名 + 行号信息,你将不得不使用私有的 CoreSymbolication 框架或编写你自己的 DWARF 解析器。
    • 根据我读到的关于 CoreSymbolication 的内容,这正是我所需要的。我会尽力。我不想写自己的 DWARF 解析器,DWARF 看起来很吓人。
    • 好吧,atos 只是一些 CoreSymbolication 函数的简单 CLI 包装器。与其处理私有框架,不如将atos 二进制文件捆绑到您的应用程序中。此外,如果您需要符号化崩溃报告,您应该查看 Xcode 的 DTDeviceKitBase 框架中的 symbol‌icatecrash 二进制文件。
    • 处理私有框架听起来并不可怕。我只是将其设为可选,以便如果那里发生更改(例如被删除),我的回溯将不包含源文件/行号信息。
    猜你喜欢
    • 2014-04-30
    • 2017-04-25
    • 2015-11-17
    • 2016-11-23
    • 1970-01-01
    • 2011-02-13
    • 1970-01-01
    • 2021-03-15
    • 2023-03-27
    相关资源
    最近更新 更多