aboutsummaryrefslogtreecommitdiff
path: root/src/common/mac
diff options
context:
space:
mode:
authorladderbreaker <ladderbreaker@4c0a9323-5329-0410-9bdc-e9ce6186880e>2007-05-03 22:58:56 +0000
committerladderbreaker <ladderbreaker@4c0a9323-5329-0410-9bdc-e9ce6186880e>2007-05-03 22:58:56 +0000
commit1fa8046e35fea128161598e016122eebda25c68a (patch)
treecb39402e4bec3818bd7a862ae07310abad795c6c /src/common/mac
parentAdd md5 implementation into code base to get rid of (diff)
downloadbreakpad-1fa8046e35fea128161598e016122eebda25c68a.tar.xz
Issue 158: reviewer ladderbreaker
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@154 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/mac')
-rw-r--r--src/common/mac/dump_syms.mm106
1 files changed, 22 insertions, 84 deletions
diff --git a/src/common/mac/dump_syms.mm b/src/common/mac/dump_syms.mm
index 427e15b3..4feb7880 100644
--- a/src/common/mac/dump_syms.mm
+++ b/src/common/mac/dump_syms.mm
@@ -31,6 +31,8 @@
#include <unistd.h>
#include <signal.h>
+#include <cxxabi.h>
+#include <stdlib.h>
#include <mach/machine.h>
#include <mach-o/arch.h>
@@ -64,8 +66,6 @@ static NSString *kUnknownSymbol = @"???";
static const int kTextSection = 1;
@interface DumpSymbols(PrivateMethods)
-- (NSString *)stringFromTask:(NSString *)action args:(NSArray *)args
- standardIn:(NSFileHandle *)standardIn;
- (NSArray *)convertCPlusPlusSymbols:(NSArray *)symbols;
- (void)convertSymbols;
- (void)addFunction:(NSString *)name line:(int)line address:(uint64_t)address section:(int)section;
@@ -81,91 +81,29 @@ static const int kTextSection = 1;
@implementation DumpSymbols
//=============================================================================
-- (NSString *)stringFromTask:(NSString *)action args:(NSArray *)args
- standardIn:(NSFileHandle *)standardIn {
- NSTask *task = [[NSTask alloc] init];
- [task setLaunchPath:action];
- NSPipe *pipe = [NSPipe pipe];
- [task setStandardOutput:pipe];
- NSFileHandle *output = [pipe fileHandleForReading];
-
- if (standardIn)
- [task setStandardInput:standardIn];
-
- if (args)
- [task setArguments:args];
-
- [task launch];
-
- // This seems a bit strange, but when using [task waitUntilExit], it hangs
- // waiting for data, but there isn't any. So, we'll poll for data,
- // take a short nap, and then ask again
- BOOL done = NO;
- NSMutableData *allData = [NSMutableData data];
- NSData *data = nil;
- int exceptionCount = 0;
-
- while (!done) {
- data = nil;
- // If there's a communications problem with the task, this might throw
- // an exception. We'll catch and keep trying.
- @try {
- data = [output availableData];
- }
- @catch (NSException *e) {
- ++exceptionCount;
- }
-
- [allData appendData:data];
-
- // Loop over the data until we're no longer returning data. If we're
- // still receiving data, sleep for 1/2 second and let the task
- // continue. If we keep receiving exceptions, bail out
- if (![data length] && data || exceptionCount > 10)
- done = YES;
- else
- usleep(500);
- }
-
- // Gather any remaining data
- [task waitUntilExit];
- data = [output availableData];
- [allData appendData:data];
- [task release];
-
- return [[[NSString alloc] initWithData:allData
- encoding:NSUTF8StringEncoding] autorelease];
-}
-
-//=============================================================================
- (NSArray *)convertCPlusPlusSymbols:(NSArray *)symbols {
- NSString *action = @"/usr/bin/c++filt";
- unsigned int count = [symbols count];
-
- // It's possible that we have too many symbols on the command line.
- // Unfortunately, c++filt doesn't take a file containing names, so we'll
- // copy the symbols to a temporary file and use that as stdin.
- char buffer[PATH_MAX];
- strlcpy(buffer, "/tmp/dump_syms_filtXXXXX", sizeof(buffer));
- int fd = mkstemp(buffer);
-
- for (unsigned int i = 0; i < count; ++i) {
- const char *symbol = [[symbols objectAtIndex:i] UTF8String];
- write(fd, symbol, strlen(symbol));
- write(fd, "\n", 1);
+ NSMutableArray *symbols_demangled = [[NSMutableArray alloc]
+ initWithCapacity:[symbols count]];
+ // __cxa_demangle will realloc this if needed
+ char *buffer = (char *)malloc(1024);
+ size_t buffer_size = 1024;
+ int result;
+
+ NSEnumerator *enumerator = [symbols objectEnumerator];
+ id symbolObject;
+ while ((symbolObject = [enumerator nextObject])) {
+ const char *symbol = [symbolObject UTF8String];
+ buffer = abi::__cxa_demangle(symbol, buffer, &buffer_size, &result);
+ if (result == 0) {
+ [symbols_demangled addObject:[NSString stringWithUTF8String:buffer]];
+ } else {
+ // unable to demangle - use mangled name instead
+ [symbols_demangled addObject:symbolObject];
+ }
}
+ free(buffer);
- // Reset to the beginning and wrap up with a file handle
- lseek(fd, 0, SEEK_SET);
- NSArray *args = [NSArray arrayWithObject:@"-n"];
- NSFileHandle *fh = [[NSFileHandle alloc] initWithFileDescriptor:fd
- closeOnDealloc:YES];
- NSArray *result = [[self stringFromTask:action args:args standardIn:fh]
- componentsSeparatedByString:@"\n"];
-
- [fh release];
-
- return result;
+ return symbols_demangled;
}
//=============================================================================