OSX相当于SymGetLineFromAddr或SymGetLineFromAddr64

时间:2015-03-24 10:51:22

标签: macos backtrace mach-o dyld dwarf

我想在我的回溯中添加源文件和行号,在Windows上有一个很好的功能SymGetLineFromAddr64,它提供了这些信息(如果有的话)。我在mac上找不到类似的东西。 dladdr仅输出没有文件信息的符号名称。

1 个答案:

答案 0 :(得分:3)

在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