OLD | NEW |
1 // Copyright (c) 2006, Google Inc. | 1 // Copyright (c) 2006, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 21 matching lines...) Expand all Loading... |
32 // code_file: the basename of the module, e.g. "app" | 32 // code_file: the basename of the module, e.g. "app" |
33 // debug_file: the basename of the debugging file, e.g. "app" | 33 // debug_file: the basename of the debugging file, e.g. "app" |
34 // debug_identifier: the debug file's identifier, usually consisting of | 34 // debug_identifier: the debug file's identifier, usually consisting of |
35 // the guid and age embedded in the pdb, e.g. | 35 // the guid and age embedded in the pdb, e.g. |
36 // "11111111BBBB3333DDDD555555555555F" | 36 // "11111111BBBB3333DDDD555555555555F" |
37 // version: the file version of the module, e.g. "1.2.3.4" | 37 // version: the file version of the module, e.g. "1.2.3.4" |
38 // os: the operating system that the module was built for | 38 // os: the operating system that the module was built for |
39 // cpu: the CPU that the module was built for | 39 // cpu: the CPU that the module was built for |
40 // symbol_file: the contents of the breakpad-format symbol file | 40 // symbol_file: the contents of the breakpad-format symbol file |
41 | 41 |
42 #include <assert.h> | |
43 #include <stdio.h> | 42 #include <stdio.h> |
44 #include <stdlib.h> | 43 #include <stdlib.h> |
45 #include <unistd.h> | 44 #include <unistd.h> |
46 | 45 |
47 #include <functional> | 46 #include "common/linux/symbol_upload.h" |
48 #include <iostream> | |
49 #include <string> | |
50 #include <vector> | |
51 | 47 |
52 #include "common/linux/http_upload.h" | 48 using google_breakpad::sym_upload::Options; |
53 #include "common/using_std_string.h" | |
54 | |
55 using google_breakpad::HTTPUpload; | |
56 | |
57 typedef struct { | |
58 string symbolsPath; | |
59 string uploadURLStr; | |
60 string proxy; | |
61 string proxy_user_pwd; | |
62 string version; | |
63 bool success; | |
64 } Options; | |
65 | |
66 static void TokenizeByChar(const string &source_string, | |
67 int c, std::vector<string> *results) { | |
68 assert(results); | |
69 string::size_type cur_pos = 0, next_pos = 0; | |
70 while ((next_pos = source_string.find(c, cur_pos)) != string::npos) { | |
71 if (next_pos != cur_pos) | |
72 results->push_back(source_string.substr(cur_pos, next_pos - cur_pos)); | |
73 cur_pos = next_pos + 1; | |
74 } | |
75 if (cur_pos < source_string.size() && next_pos != cur_pos) | |
76 results->push_back(source_string.substr(cur_pos)); | |
77 } | |
78 | |
79 //============================================================================= | |
80 // Parse out the module line which have 5 parts. | |
81 // MODULE <os> <cpu> <uuid> <module-name> | |
82 static bool ModuleDataForSymbolFile(const string &file, | |
83 std::vector<string> *module_parts) { | |
84 assert(module_parts); | |
85 const size_t kModulePartNumber = 5; | |
86 FILE* fp = fopen(file.c_str(), "r"); | |
87 if (fp) { | |
88 char buffer[1024]; | |
89 if (fgets(buffer, sizeof(buffer), fp)) { | |
90 string line(buffer); | |
91 string::size_type line_break_pos = line.find_first_of('\n'); | |
92 if (line_break_pos == string::npos) { | |
93 assert(0 && "The file is invalid!"); | |
94 fclose(fp); | |
95 return false; | |
96 } | |
97 line.resize(line_break_pos); | |
98 const char kDelimiter = ' '; | |
99 TokenizeByChar(line, kDelimiter, module_parts); | |
100 if (module_parts->size() != kModulePartNumber) | |
101 module_parts->clear(); | |
102 } | |
103 fclose(fp); | |
104 } | |
105 | |
106 return module_parts->size() == kModulePartNumber; | |
107 } | |
108 | |
109 //============================================================================= | |
110 static string CompactIdentifier(const string &uuid) { | |
111 std::vector<string> components; | |
112 TokenizeByChar(uuid, '-', &components); | |
113 string result; | |
114 for (size_t i = 0; i < components.size(); ++i) | |
115 result += components[i]; | |
116 return result; | |
117 } | |
118 | |
119 //============================================================================= | |
120 static void Start(Options *options) { | |
121 std::map<string, string> parameters; | |
122 options->success = false; | |
123 std::vector<string> module_parts; | |
124 if (!ModuleDataForSymbolFile(options->symbolsPath, &module_parts)) { | |
125 fprintf(stderr, "Failed to parse symbol file!\n"); | |
126 return; | |
127 } | |
128 | |
129 string compacted_id = CompactIdentifier(module_parts[3]); | |
130 | |
131 // Add parameters | |
132 if (!options->version.empty()) | |
133 parameters["version"] = options->version; | |
134 | |
135 // MODULE <os> <cpu> <uuid> <module-name> | |
136 // 0 1 2 3 4 | |
137 parameters["os"] = module_parts[1]; | |
138 parameters["cpu"] = module_parts[2]; | |
139 parameters["debug_file"] = module_parts[4]; | |
140 parameters["code_file"] = module_parts[4]; | |
141 parameters["debug_identifier"] = compacted_id; | |
142 | |
143 std::map<string, string> files; | |
144 files["symbol_file"] = options->symbolsPath; | |
145 | |
146 string response, error; | |
147 long response_code; | |
148 bool success = HTTPUpload::SendRequest(options->uploadURLStr, | |
149 parameters, | |
150 files, | |
151 options->proxy, | |
152 options->proxy_user_pwd, | |
153 "", | |
154 &response, | |
155 &response_code, | |
156 &error); | |
157 | |
158 if (!success) { | |
159 printf("Failed to send symbol file: %s\n", error.c_str()); | |
160 printf("Response code: %ld\n", response_code); | |
161 printf("Response:\n"); | |
162 printf("%s\n", response.c_str()); | |
163 } else if (response_code == 0) { | |
164 printf("Failed to send symbol file: No response code\n"); | |
165 } else if (response_code != 200) { | |
166 printf("Failed to send symbol file: Response code %ld\n", response_code); | |
167 printf("Response:\n"); | |
168 printf("%s\n", response.c_str()); | |
169 } else { | |
170 printf("Successfully sent the symbol file.\n"); | |
171 } | |
172 options->success = success; | |
173 } | |
174 | 49 |
175 //============================================================================= | 50 //============================================================================= |
176 static void | 51 static void |
177 Usage(int argc, const char *argv[]) { | 52 Usage(int argc, const char *argv[]) { |
178 fprintf(stderr, "Submit symbol information.\n"); | 53 fprintf(stderr, "Submit symbol information.\n"); |
179 fprintf(stderr, "Usage: %s [options...] <symbols> <upload-URL>\n", argv[0]); | 54 fprintf(stderr, "Usage: %s [options...] <symbols> <upload-URL>\n", argv[0]); |
180 fprintf(stderr, "Options:\n"); | 55 fprintf(stderr, "Options:\n"); |
181 fprintf(stderr, "<symbols> should be created by using the dump_syms tool.\n"); | 56 fprintf(stderr, "<symbols> should be created by using the dump_syms tool.\n"); |
182 fprintf(stderr, "<upload-URL> is the destination for the upload\n"); | 57 fprintf(stderr, "<upload-URL> is the destination for the upload\n"); |
183 fprintf(stderr, "-v:\t Version information (e.g., 1.2.3.4)\n"); | 58 fprintf(stderr, "-v:\t Version information (e.g., 1.2.3.4)\n"); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 } | 100 } |
226 | 101 |
227 options->symbolsPath = argv[optind]; | 102 options->symbolsPath = argv[optind]; |
228 options->uploadURLStr = argv[optind + 1]; | 103 options->uploadURLStr = argv[optind + 1]; |
229 } | 104 } |
230 | 105 |
231 //============================================================================= | 106 //============================================================================= |
232 int main(int argc, const char* argv[]) { | 107 int main(int argc, const char* argv[]) { |
233 Options options; | 108 Options options; |
234 SetupOptions(argc, argv, &options); | 109 SetupOptions(argc, argv, &options); |
235 Start(&options); | 110 google_breakpad::sym_upload::Start(&options); |
236 return options.success ? 0 : 1; | 111 return options.success ? 0 : 1; |
237 } | 112 } |
OLD | NEW |