mirror of
https://github.com/yuzu-emu/breakpad
synced 2024-11-25 14:08:56 +00:00
Add native symbol uploads to Mac OS symupload tool.
- sym-upload-v2 protocol only. - Supports elf, dwp, debug_only, macho, dsym, pe, and pdb (with the classic mode being called 'breakpad'). Change-Id: I68c0065aec3a7ffe29b364dd9e2e1dbdb58e3e5d Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2357528 Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
62d9272419
commit
9c38ab7c67
3 changed files with 127 additions and 30 deletions
|
@ -95,7 +95,8 @@ typedef NS_ENUM(NSInteger, SymbolStatus) {
|
||||||
withAPIKey:(NSString*)APIKey
|
withAPIKey:(NSString*)APIKey
|
||||||
withUploadKey:(NSString*)uploadKey
|
withUploadKey:(NSString*)uploadKey
|
||||||
withDebugFile:(NSString*)debugFile
|
withDebugFile:(NSString*)debugFile
|
||||||
withDebugID:(NSString*)debugID;
|
withDebugID:(NSString*)debugID
|
||||||
|
withType:(NSString*)type;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -77,9 +77,9 @@
|
||||||
[allowedDebugFileCharacters
|
[allowedDebugFileCharacters
|
||||||
formUnionWithCharacterSet:[NSCharacterSet controlCharacterSet]];
|
formUnionWithCharacterSet:[NSCharacterSet controlCharacterSet]];
|
||||||
[allowedDebugFileCharacters invert];
|
[allowedDebugFileCharacters invert];
|
||||||
NSString* escapedDebugFile = [debugFile
|
NSString* escapedDebugFile =
|
||||||
stringByAddingPercentEncodingWithAllowedCharacters:
|
[debugFile stringByAddingPercentEncodingWithAllowedCharacters:
|
||||||
allowedDebugFileCharacters];
|
allowedDebugFileCharacters];
|
||||||
|
|
||||||
NSURL* URL = [NSURL
|
NSURL* URL = [NSURL
|
||||||
URLWithString:[NSString
|
URLWithString:[NSString
|
||||||
|
@ -189,7 +189,8 @@
|
||||||
withAPIKey:(NSString*)APIKey
|
withAPIKey:(NSString*)APIKey
|
||||||
withUploadKey:(NSString*)uploadKey
|
withUploadKey:(NSString*)uploadKey
|
||||||
withDebugFile:(NSString*)debugFile
|
withDebugFile:(NSString*)debugFile
|
||||||
withDebugID:(NSString*)debugID {
|
withDebugID:(NSString*)debugID
|
||||||
|
withType:(NSString*)type {
|
||||||
NSURL* URL = [NSURL
|
NSURL* URL = [NSURL
|
||||||
URLWithString:[NSString
|
URLWithString:[NSString
|
||||||
stringWithFormat:@"%@/v1/uploads/%@:complete?key=%@",
|
stringWithFormat:@"%@/v1/uploads/%@:complete?key=%@",
|
||||||
|
@ -199,7 +200,8 @@
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:debugFile, @"debug_file",
|
[NSDictionary dictionaryWithObjectsAndKeys:debugFile, @"debug_file",
|
||||||
debugID, @"debug_id", nil];
|
debugID, @"debug_id", nil];
|
||||||
NSDictionary* jsonDictionary = [NSDictionary
|
NSDictionary* jsonDictionary = [NSDictionary
|
||||||
dictionaryWithObjectsAndKeys:symbolIdDictionary, @"symbol_id", nil];
|
dictionaryWithObjectsAndKeys:symbolIdDictionary, @"symbol_id", type,
|
||||||
|
@"symbol_upload_type", nil];
|
||||||
NSError* error;
|
NSError* error;
|
||||||
NSData* jsonData =
|
NSData* jsonData =
|
||||||
[NSJSONSerialization dataWithJSONObject:jsonDictionary
|
[NSJSONSerialization dataWithJSONObject:jsonDictionary
|
||||||
|
|
|
@ -48,6 +48,8 @@
|
||||||
#include "HTTPPutRequest.h"
|
#include "HTTPPutRequest.h"
|
||||||
#include "SymbolCollectorClient.h"
|
#include "SymbolCollectorClient.h"
|
||||||
|
|
||||||
|
NSString* const kBreakpadSymbolType = @"BREAKPAD";
|
||||||
|
|
||||||
typedef enum { kSymUploadProtocolV1, kSymUploadProtocolV2 } SymUploadProtocol;
|
typedef enum { kSymUploadProtocolV1, kSymUploadProtocolV2 } SymUploadProtocol;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -63,6 +65,9 @@ typedef struct {
|
||||||
NSString* apiKey;
|
NSString* apiKey;
|
||||||
BOOL force;
|
BOOL force;
|
||||||
Result result;
|
Result result;
|
||||||
|
NSString* type;
|
||||||
|
NSString* codeFile;
|
||||||
|
NSString* debugID;
|
||||||
} Options;
|
} Options;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -100,21 +105,20 @@ static NSArray* ModuleDataForSymbolFile(NSString* file) {
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
static void StartSymUploadProtocolV1(Options* options,
|
static void StartSymUploadProtocolV1(Options* options,
|
||||||
NSArray* moduleParts,
|
NSString* OS,
|
||||||
NSString* compactedID) {
|
NSString* CPU,
|
||||||
|
NSString* debugID,
|
||||||
|
NSString* debugFile) {
|
||||||
NSURL* url = [NSURL URLWithString:options->uploadURLStr];
|
NSURL* url = [NSURL URLWithString:options->uploadURLStr];
|
||||||
HTTPMultipartUpload* ul = [[HTTPMultipartUpload alloc] initWithURL:url];
|
HTTPMultipartUpload* ul = [[HTTPMultipartUpload alloc] initWithURL:url];
|
||||||
NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
|
NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
|
||||||
|
|
||||||
// Add parameters
|
// Add parameters
|
||||||
[parameters setObject:compactedID forKey:@"debug_identifier"];
|
[parameters setObject:debugID forKey:@"debug_identifier"];
|
||||||
|
[parameters setObject:OS forKey:@"os"];
|
||||||
// MODULE <os> <cpu> <uuid> <module-name>
|
[parameters setObject:CPU forKey:@"cpu"];
|
||||||
// 0 1 2 3 4
|
[parameters setObject:debugFile forKey:@"debug_file"];
|
||||||
[parameters setObject:[moduleParts objectAtIndex:1] forKey:@"os"];
|
[parameters setObject:debugFile forKey:@"code_file"];
|
||||||
[parameters setObject:[moduleParts objectAtIndex:2] forKey:@"cpu"];
|
|
||||||
[parameters setObject:[moduleParts objectAtIndex:4] forKey:@"debug_file"];
|
|
||||||
[parameters setObject:[moduleParts objectAtIndex:4] forKey:@"code_file"];
|
|
||||||
[ul setParameters:parameters];
|
[ul setParameters:parameters];
|
||||||
|
|
||||||
NSArray* keys = [parameters allKeys];
|
NSArray* keys = [parameters allKeys];
|
||||||
|
@ -148,12 +152,13 @@ static void StartSymUploadProtocolV1(Options* options,
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
static void StartSymUploadProtocolV2(Options* options,
|
static void StartSymUploadProtocolV2(Options* options,
|
||||||
NSArray* moduleParts,
|
NSString* debugID,
|
||||||
NSString* debugID) {
|
NSString* debugFile) {
|
||||||
options->result = kResultFailure;
|
options->result = kResultFailure;
|
||||||
|
|
||||||
NSString* debugFile = [moduleParts objectAtIndex:4];
|
// Only check status of BREAKPAD symbols, because the v2 protocol doesn't
|
||||||
if (!options->force) {
|
// (yet) have a way to check status of other symbol types.
|
||||||
|
if (!options->force && [options->type isEqualToString:kBreakpadSymbolType]) {
|
||||||
SymbolStatus symbolStatus =
|
SymbolStatus symbolStatus =
|
||||||
[SymbolCollectorClient checkSymbolStatusOnServer:options->uploadURLStr
|
[SymbolCollectorClient checkSymbolStatusOnServer:options->uploadURLStr
|
||||||
withAPIKey:options->apiKey
|
withAPIKey:options->apiKey
|
||||||
|
@ -201,7 +206,8 @@ static void StartSymUploadProtocolV2(Options* options,
|
||||||
withAPIKey:options->apiKey
|
withAPIKey:options->apiKey
|
||||||
withUploadKey:[URLResponse uploadKey]
|
withUploadKey:[URLResponse uploadKey]
|
||||||
withDebugFile:debugFile
|
withDebugFile:debugFile
|
||||||
withDebugID:debugID];
|
withDebugID:debugID
|
||||||
|
withType:options->type];
|
||||||
[URLResponse release];
|
[URLResponse release];
|
||||||
if (completeUploadResult == CompleteUploadResultError) {
|
if (completeUploadResult == CompleteUploadResultError) {
|
||||||
fprintf(stdout, "Failed to complete upload.\n");
|
fprintf(stdout, "Failed to complete upload.\n");
|
||||||
|
@ -217,18 +223,29 @@ static void StartSymUploadProtocolV2(Options* options,
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
static void Start(Options* options) {
|
static void Start(Options* options) {
|
||||||
|
// If non-BREAKPAD upload special-case.
|
||||||
|
if (![options->type isEqualToString:kBreakpadSymbolType]) {
|
||||||
|
StartSymUploadProtocolV2(options, options->debugID, options->codeFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NSArray* moduleParts = ModuleDataForSymbolFile(options->symbolsPath);
|
NSArray* moduleParts = ModuleDataForSymbolFile(options->symbolsPath);
|
||||||
NSMutableString* compactedID =
|
// MODULE <os> <cpu> <uuid> <module-name>
|
||||||
|
// 0 1 2 3 4
|
||||||
|
NSString* OS = [moduleParts objectAtIndex:1];
|
||||||
|
NSString* CPU = [moduleParts objectAtIndex:2];
|
||||||
|
NSMutableString* debugID =
|
||||||
[NSMutableString stringWithString:[moduleParts objectAtIndex:3]];
|
[NSMutableString stringWithString:[moduleParts objectAtIndex:3]];
|
||||||
[compactedID replaceOccurrencesOfString:@"-"
|
[debugID replaceOccurrencesOfString:@"-"
|
||||||
withString:@""
|
withString:@""
|
||||||
options:0
|
options:0
|
||||||
range:NSMakeRange(0, [compactedID length])];
|
range:NSMakeRange(0, [debugID length])];
|
||||||
|
NSString* debugFile = [moduleParts objectAtIndex:4];
|
||||||
|
|
||||||
if (options->symUploadProtocol == kSymUploadProtocolV1) {
|
if (options->symUploadProtocol == kSymUploadProtocolV1) {
|
||||||
StartSymUploadProtocolV1(options, moduleParts, compactedID);
|
StartSymUploadProtocolV1(options, OS, CPU, debugID, debugFile);
|
||||||
} else if (options->symUploadProtocol == kSymUploadProtocolV2) {
|
} else if (options->symUploadProtocol == kSymUploadProtocolV2) {
|
||||||
StartSymUploadProtocolV2(options, moduleParts, compactedID);
|
StartSymUploadProtocolV2(options, debugID, debugFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,8 +264,21 @@ static void Usage(int argc, const char* argv[]) {
|
||||||
"server. [Only in sym-upload-v2 protocol mode]\n");
|
"server. [Only in sym-upload-v2 protocol mode]\n");
|
||||||
fprintf(stderr, "\t-f: Overwrite symbol file on server if already present. "
|
fprintf(stderr, "\t-f: Overwrite symbol file on server if already present. "
|
||||||
"[Only in sym-upload-v2 protocol mode]\n");
|
"[Only in sym-upload-v2 protocol mode]\n");
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"-t:\t <symbol-type> Explicitly set symbol upload type ("
|
||||||
|
"default is 'breakpad').\n"
|
||||||
|
"\t One of ['breakpad', 'elf', 'pe', 'macho', 'debug_only', 'dwp', "
|
||||||
|
"'dsym', 'pdb'].\n"
|
||||||
|
"\t Note: When this flag is set to anything other than 'breakpad', then "
|
||||||
|
"the '-c' and '-i' flags must also be set.\n");
|
||||||
|
fprintf(stderr, "-c:\t <code-file> Explicitly set 'code_file' for symbol "
|
||||||
|
"upload (basename of executable).\n");
|
||||||
|
fprintf(stderr, "-i:\t <debug-id> Explicitly set 'debug_id' for symbol "
|
||||||
|
"upload (typically build ID of executable).\n");
|
||||||
fprintf(stderr, "\t-h: Usage\n");
|
fprintf(stderr, "\t-h: Usage\n");
|
||||||
fprintf(stderr, "\t-?: Usage\n");
|
fprintf(stderr, "\t-?: Usage\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "Exit codes:\n");
|
fprintf(stderr, "Exit codes:\n");
|
||||||
fprintf(stderr, "\t%d: Success\n", kResultSuccess);
|
fprintf(stderr, "\t%d: Success\n", kResultSuccess);
|
||||||
fprintf(stderr, "\t%d: Failure\n", kResultFailure);
|
fprintf(stderr, "\t%d: Failure\n", kResultFailure);
|
||||||
|
@ -264,17 +294,39 @@ static void Usage(int argc, const char* argv[]) {
|
||||||
"Failure\n");
|
"Failure\n");
|
||||||
fprintf(stderr, "\t in this case, and the action taken by the server is "
|
fprintf(stderr, "\t in this case, and the action taken by the server is "
|
||||||
"unspecified.]\n");
|
"unspecified.]\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "Examples:\n");
|
||||||
|
fprintf(stderr, " With 'sym-upload-v1':\n");
|
||||||
|
fprintf(stderr, " %s path/to/symbol_file http://myuploadserver\n",
|
||||||
|
argv[0]);
|
||||||
|
fprintf(stderr, " With 'sym-upload-v2':\n");
|
||||||
|
fprintf(stderr, " [Defaulting to symbol type 'BREAKPAD']\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" %s -p sym-upload-v2 -k mysecret123! "
|
||||||
|
"path/to/symbol_file http://myuploadserver\n",
|
||||||
|
argv[0]);
|
||||||
|
fprintf(stderr, " [Explicitly set symbol type to 'macho']\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" %s -p sym-upload-v2 -k mysecret123! -t macho "
|
||||||
|
"-c app -i 11111111BBBB3333DDDD555555555555F "
|
||||||
|
"path/to/symbol_file http://myuploadserver\n",
|
||||||
|
argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
static void SetupOptions(int argc, const char* argv[], Options* options) {
|
static void SetupOptions(int argc, const char* argv[], Options* options) {
|
||||||
// Set default value of symUploadProtocol.
|
// Set default options values.
|
||||||
options->symUploadProtocol = kSymUploadProtocolV1;
|
options->symUploadProtocol = kSymUploadProtocolV1;
|
||||||
|
options->apiKey = nil;
|
||||||
|
options->type = kBreakpadSymbolType;
|
||||||
|
options->codeFile = nil;
|
||||||
|
options->debugID = nil;
|
||||||
|
options->force = NO;
|
||||||
|
|
||||||
extern int optind;
|
extern int optind;
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
while ((ch = getopt(argc, (char* const*)argv, "p:k:hf?")) != -1) {
|
while ((ch = getopt(argc, (char* const*)argv, "p:k:t:c:i:hf?")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'p':
|
case 'p':
|
||||||
if (strcmp(optarg, "sym-upload-v2") == 0) {
|
if (strcmp(optarg, "sym-upload-v2") == 0) {
|
||||||
|
@ -292,6 +344,24 @@ static void SetupOptions(int argc, const char* argv[], Options* options) {
|
||||||
options->apiKey = [NSString stringWithCString:optarg
|
options->apiKey = [NSString stringWithCString:optarg
|
||||||
encoding:NSASCIIStringEncoding];
|
encoding:NSASCIIStringEncoding];
|
||||||
break;
|
break;
|
||||||
|
case 't': {
|
||||||
|
// This is really an enum, so treat as upper-case for consistency with
|
||||||
|
// enum naming convention on server-side.
|
||||||
|
options->type = [[NSString stringWithCString:optarg
|
||||||
|
encoding:NSASCIIStringEncoding]
|
||||||
|
uppercaseString];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'c':
|
||||||
|
options->codeFile = [NSString stringWithCString:optarg
|
||||||
|
encoding:NSASCIIStringEncoding];
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
options->debugID = [NSString stringWithCString:optarg
|
||||||
|
encoding:NSASCIIStringEncoding];
|
||||||
|
;
|
||||||
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
options->force = YES;
|
options->force = YES;
|
||||||
break;
|
break;
|
||||||
|
@ -327,6 +397,30 @@ static void SetupOptions(int argc, const char* argv[], Options* options) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isBreakpadUpload = [options->type isEqualToString:kBreakpadSymbolType];
|
||||||
|
bool hasCodeFile = options->codeFile != nil;
|
||||||
|
bool hasDebugID = options->debugID != nil;
|
||||||
|
if (isBreakpadUpload && (hasCodeFile || hasDebugID)) {
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: -c and -i should only be specified for non-breakpad "
|
||||||
|
"symbol upload types.\n",
|
||||||
|
argv[0]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
Usage(argc, argv);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!isBreakpadUpload && (!hasCodeFile || !hasDebugID)) {
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: -c and -i must be specified for non-breakpad "
|
||||||
|
"symbol upload types.\n",
|
||||||
|
argv[0]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
Usage(argc, argv);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
options->symbolsPath = [NSString stringWithUTF8String:argv[optind]];
|
options->symbolsPath = [NSString stringWithUTF8String:argv[optind]];
|
||||||
options->uploadURLStr = [NSString stringWithUTF8String:argv[optind + 1]];
|
options->uploadURLStr = [NSString stringWithUTF8String:argv[optind + 1]];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue