aboutsummaryrefslogtreecommitdiff
path: root/src/common/mac
diff options
context:
space:
mode:
authormmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e>2007-04-12 20:40:22 +0000
committermmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e>2007-04-12 20:40:22 +0000
commit1d4ce0a1d80811b75aef3bbd69216d7838b560cd (patch)
tree5185532b6c50af76f67090bca177e73d707a6ff9 /src/common/mac
parentIssue 147 - reviewer Waylonis (diff)
downloadbreakpad-1d4ce0a1d80811b75aef3bbd69216d7838b560cd.tar.xz
c++filt crashes when fed some mangled ObjC++ names. Oops. Patch by Dave
MacLachlan, r=me. git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@145 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/mac')
-rw-r--r--src/common/mac/dump_syms.mm74
1 files changed, 37 insertions, 37 deletions
diff --git a/src/common/mac/dump_syms.mm b/src/common/mac/dump_syms.mm
index 6541285e..b122b54b 100644
--- a/src/common/mac/dump_syms.mm
+++ b/src/common/mac/dump_syms.mm
@@ -77,26 +77,6 @@ static const int kTextSection = 1;
- (BOOL)loadModuleInfo;
@end
-static BOOL StringHeadMatches(NSString *str, NSString *head) {
- int headLen = [head length];
- int strLen = [str length];
-
- if (headLen > strLen)
- return NO;
-
- return [[str substringToIndex:headLen] isEqualToString:head];
-}
-
-static BOOL StringTailMatches(NSString *str, NSString *tail) {
- int tailLen = [tail length];
- int strLen = [str length];
-
- if (tailLen > strLen)
- return NO;
-
- return [[str substringFromIndex:strLen - tailLen] isEqualToString:tail];
-}
-
@implementation DumpSymbols
//=============================================================================
- (NSString *)stringFromTask:(NSString *)action args:(NSArray *)args
@@ -164,13 +144,13 @@ static BOOL StringTailMatches(NSString *str, NSString *tail) {
// 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];
- snprintf(buffer, sizeof(buffer), "/tmp/dump_syms_filtXXXXX");
+ strlcpy(buffer, "/tmp/dump_syms_filtXXXXX", sizeof(buffer));
int fd = mkstemp(buffer);
- char nl = '\n';
+
for (unsigned int i = 0; i < count; ++i) {
const char *symbol = [[symbols objectAtIndex:i] UTF8String];
write(fd, symbol, strlen(symbol));
- write(fd, &nl, 1);
+ write(fd, "\n", 1);
}
// Reset to the beginning and wrap up with a file handle
@@ -254,25 +234,45 @@ static BOOL StringTailMatches(NSString *str, NSString *tail) {
// addresses to run through the c++filt
BOOL isCPP = NO;
- if (StringHeadMatches(name, @"__Z")) {
+ if ([name hasPrefix:@"__Z"]) {
// Remove the leading underscore
name = [name substringFromIndex:1];
isCPP = YES;
- } else if (StringHeadMatches(name, @"_Z")) {
+ } else if ([name hasPrefix:@"_Z"]) {
isCPP = YES;
}
// Filter out non-functions
- if (StringTailMatches(name, @".eh"))
+ if ([name hasSuffix:@".eh"])
return;
- if (StringTailMatches(name, @"__func__"))
+ if ([name hasSuffix:@"__func__"])
return;
- if (StringTailMatches(name, @"GCC_except_table"))
+ if ([name hasSuffix:@"GCC_except_table"])
return;
if (isCPP) {
+ // OBJCPP_MANGLING_HACK
+ // There are cases where ObjC++ mangles up an ObjC name using quasi-C++
+ // mangling:
+ // @implementation Foozles + (void)barzles {
+ // static int Baz = 0;
+ // } @end
+ // gives you _ZZ18+[Foozles barzles]E3Baz
+ // c++filt won't parse this properly, and will crash in certain cases.
+ // Logged as radar:
+ // 5129938: c++filt does not deal with ObjC++ symbols
+ // If 5129938 ever gets fixed, we can remove this, but for now this prevents
+ // c++filt from attempting to demangle names it doesn't know how to handle.
+ // This is with c++filt 2.16
+ NSCharacterSet *objcppCharSet = [NSCharacterSet characterSetWithCharactersInString:@"-+[]: "];
+ NSRange emptyRange = { NSNotFound, 0 };
+ NSRange objcppRange = [name rangeOfCharacterFromSet:objcppCharSet];
+ isCPP = NSEqualRanges(objcppRange, emptyRange);
+ }
+
+ if (isCPP) {
if (!cppAddresses_)
cppAddresses_ = [[NSMutableArray alloc] init];
[cppAddresses_ addObject:addressNum];
@@ -321,7 +321,7 @@ static BOOL StringTailMatches(NSString *str, NSString *tail) {
// an N_FUN from section 0 may follow the initial N_FUN
// giving us function length information
NSMutableDictionary *dict = [addresses_ objectForKey:
- [NSNumber numberWithUnsignedLong:lastStartAddress_] ];
+ [NSNumber numberWithUnsignedLong:lastStartAddress_]];
assert(dict);
@@ -788,28 +788,28 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
}
// Skip some symbols
- if (StringHeadMatches(symbol, @"vtable for"))
+ if ([symbol hasPrefix:@"vtable for"])
continue;
- if (StringHeadMatches(symbol, @"__static_initialization_and_destruction_0"))
+ if ([symbol hasPrefix:@"__static_initialization_and_destruction_0"])
continue;
- if (StringHeadMatches(symbol, @"_GLOBAL__I__"))
+ if ([symbol hasPrefix:@"_GLOBAL__I__"])
continue;
- if (StringHeadMatches(symbol, @"__func__."))
+ if ([symbol hasPrefix:@"__func__."])
continue;
- if (StringHeadMatches(symbol, @"__gnu"))
+ if ([symbol hasPrefix:@"__gnu"])
continue;
- if (StringHeadMatches(symbol, @"typeinfo "))
+ if ([symbol hasPrefix:@"typeinfo "])
continue;
- if (StringHeadMatches(symbol, @"EH_frame"))
+ if ([symbol hasPrefix:@"EH_frame"])
continue;
- if (StringHeadMatches(symbol, @"GCC_except_table"))
+ if ([symbol hasPrefix:@"GCC_except_table"])
continue;
// Find the source file (if any) that contains this address