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
This commit is contained in:
parent
e9017f3239
commit
1d4ce0a1d8
1 changed files with 37 additions and 37 deletions
|
@ -77,26 +77,6 @@ static const int kTextSection = 1;
|
||||||
- (BOOL)loadModuleInfo;
|
- (BOOL)loadModuleInfo;
|
||||||
@end
|
@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
|
@implementation DumpSymbols
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
- (NSString *)stringFromTask:(NSString *)action args:(NSArray *)args
|
- (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
|
// 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.
|
// copy the symbols to a temporary file and use that as stdin.
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
snprintf(buffer, sizeof(buffer), "/tmp/dump_syms_filtXXXXX");
|
strlcpy(buffer, "/tmp/dump_syms_filtXXXXX", sizeof(buffer));
|
||||||
int fd = mkstemp(buffer);
|
int fd = mkstemp(buffer);
|
||||||
char nl = '\n';
|
|
||||||
for (unsigned int i = 0; i < count; ++i) {
|
for (unsigned int i = 0; i < count; ++i) {
|
||||||
const char *symbol = [[symbols objectAtIndex:i] UTF8String];
|
const char *symbol = [[symbols objectAtIndex:i] UTF8String];
|
||||||
write(fd, symbol, strlen(symbol));
|
write(fd, symbol, strlen(symbol));
|
||||||
write(fd, &nl, 1);
|
write(fd, "\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset to the beginning and wrap up with a file handle
|
// Reset to the beginning and wrap up with a file handle
|
||||||
|
@ -254,24 +234,44 @@ static BOOL StringTailMatches(NSString *str, NSString *tail) {
|
||||||
// addresses to run through the c++filt
|
// addresses to run through the c++filt
|
||||||
BOOL isCPP = NO;
|
BOOL isCPP = NO;
|
||||||
|
|
||||||
if (StringHeadMatches(name, @"__Z")) {
|
if ([name hasPrefix:@"__Z"]) {
|
||||||
// Remove the leading underscore
|
// Remove the leading underscore
|
||||||
name = [name substringFromIndex:1];
|
name = [name substringFromIndex:1];
|
||||||
isCPP = YES;
|
isCPP = YES;
|
||||||
} else if (StringHeadMatches(name, @"_Z")) {
|
} else if ([name hasPrefix:@"_Z"]) {
|
||||||
isCPP = YES;
|
isCPP = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter out non-functions
|
// Filter out non-functions
|
||||||
if (StringTailMatches(name, @".eh"))
|
if ([name hasSuffix:@".eh"])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (StringTailMatches(name, @"__func__"))
|
if ([name hasSuffix:@"__func__"])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (StringTailMatches(name, @"GCC_except_table"))
|
if ([name hasSuffix:@"GCC_except_table"])
|
||||||
return;
|
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 (isCPP) {
|
||||||
if (!cppAddresses_)
|
if (!cppAddresses_)
|
||||||
cppAddresses_ = [[NSMutableArray alloc] init];
|
cppAddresses_ = [[NSMutableArray alloc] init];
|
||||||
|
@ -321,7 +321,7 @@ static BOOL StringTailMatches(NSString *str, NSString *tail) {
|
||||||
// an N_FUN from section 0 may follow the initial N_FUN
|
// an N_FUN from section 0 may follow the initial N_FUN
|
||||||
// giving us function length information
|
// giving us function length information
|
||||||
NSMutableDictionary *dict = [addresses_ objectForKey:
|
NSMutableDictionary *dict = [addresses_ objectForKey:
|
||||||
[NSNumber numberWithUnsignedLong:lastStartAddress_] ];
|
[NSNumber numberWithUnsignedLong:lastStartAddress_]];
|
||||||
|
|
||||||
assert(dict);
|
assert(dict);
|
||||||
|
|
||||||
|
@ -788,28 +788,28 @@ static BOOL WriteFormat(int fd, const char *fmt, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip some symbols
|
// Skip some symbols
|
||||||
if (StringHeadMatches(symbol, @"vtable for"))
|
if ([symbol hasPrefix:@"vtable for"])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (StringHeadMatches(symbol, @"__static_initialization_and_destruction_0"))
|
if ([symbol hasPrefix:@"__static_initialization_and_destruction_0"])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (StringHeadMatches(symbol, @"_GLOBAL__I__"))
|
if ([symbol hasPrefix:@"_GLOBAL__I__"])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (StringHeadMatches(symbol, @"__func__."))
|
if ([symbol hasPrefix:@"__func__."])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (StringHeadMatches(symbol, @"__gnu"))
|
if ([symbol hasPrefix:@"__gnu"])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (StringHeadMatches(symbol, @"typeinfo "))
|
if ([symbol hasPrefix:@"typeinfo "])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (StringHeadMatches(symbol, @"EH_frame"))
|
if ([symbol hasPrefix:@"EH_frame"])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (StringHeadMatches(symbol, @"GCC_except_table"))
|
if ([symbol hasPrefix:@"GCC_except_table"])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Find the source file (if any) that contains this address
|
// Find the source file (if any) that contains this address
|
||||||
|
|
Loading…
Reference in a new issue