OLD | NEW |
---|---|
1 // Copyright (c) 2006, Google Inc. | 1 // Copyright (c) 2011 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 |
11 // copyright notice, this list of conditions and the following disclaimer | 11 // copyright notice, this list of conditions and the following disclaimer |
12 // in the documentation and/or other materials provided with the | 12 // in the documentation and/or other materials provided with the |
13 // distribution. | 13 // distribution. |
14 // * Neither the name of Google Inc. nor the names of its | 14 // * Neither the name of Google Inc. nor the names of its |
15 // contributors may be used to endorse or promote products derived from | 15 // contributors may be used to endorse or promote products derived from |
16 // this software without specific prior written permission. | 16 // this software without specific prior written permission. |
17 // | 17 // |
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 // symupload.cc: Upload a symbol file to a HTTP server. The upload is sent as | 30 // symbol_upload.cc: implemented google_breakpad::sym_upload::Start, a helper |
31 // a multipart/form-data POST request with the following parameters: | 31 // function for linux symbol upload tool. |
32 // code_file: the basename of the module, e.g. "app" | 32 |
33 // debug_file: the basename of the debugging file, e.g. "app" | 33 #include "common/linux/http_upload.h" |
34 // debug_identifier: the debug file's identifier, usually consisting of | 34 #include "common/linux/symbol_upload.h" |
35 // the guid and age embedded in the pdb, e.g. | |
36 // "11111111BBBB3333DDDD555555555555F" | |
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 | |
39 // cpu: the CPU that the module was built for | |
40 // symbol_file: the contents of the breakpad-format symbol file | |
41 | 35 |
42 #include <assert.h> | 36 #include <assert.h> |
43 #include <stdio.h> | 37 #include <stdio.h> |
44 #include <stdlib.h> | |
45 #include <unistd.h> | |
46 | 38 |
47 #include <functional> | 39 #include <functional> |
48 #include <iostream> | |
49 #include <string> | |
50 #include <vector> | 40 #include <vector> |
51 | 41 |
52 #include "common/linux/http_upload.h" | 42 namespace google_breakpad { |
53 #include "common/using_std_string.h" | 43 namespace sym_upload { |
54 | 44 |
55 using google_breakpad::HTTPUpload; | 45 void TokenizeByChar(const string &source_string, |
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) { | 46 int c, std::vector<string> *results) { |
mmandlis
2016/03/30 18:34:40
nit, please, fix indentation.
| |
68 assert(results); | 47 assert(results); |
69 string::size_type cur_pos = 0, next_pos = 0; | 48 string::size_type cur_pos = 0, next_pos = 0; |
70 while ((next_pos = source_string.find(c, cur_pos)) != string::npos) { | 49 while ((next_pos = source_string.find(c, cur_pos)) != string::npos) { |
71 if (next_pos != cur_pos) | 50 if (next_pos != cur_pos) |
72 results->push_back(source_string.substr(cur_pos, next_pos - cur_pos)); | 51 results->push_back(source_string.substr(cur_pos, next_pos - cur_pos)); |
73 cur_pos = next_pos + 1; | 52 cur_pos = next_pos + 1; |
74 } | 53 } |
75 if (cur_pos < source_string.size() && next_pos != cur_pos) | 54 if (cur_pos < source_string.size() && next_pos != cur_pos) |
76 results->push_back(source_string.substr(cur_pos)); | 55 results->push_back(source_string.substr(cur_pos)); |
77 } | 56 } |
78 | 57 |
79 //============================================================================= | 58 //============================================================================= |
80 // Parse out the module line which have 5 parts. | 59 // Parse out the module line which have 5 parts. |
81 // MODULE <os> <cpu> <uuid> <module-name> | 60 // MODULE <os> <cpu> <uuid> <module-name> |
82 static bool ModuleDataForSymbolFile(const string &file, | 61 bool ModuleDataForSymbolFile(const string &file, |
83 std::vector<string> *module_parts) { | 62 std::vector<string> *module_parts) { |
mmandlis
2016/03/30 18:34:40
nit, please, fix indentation.
| |
84 assert(module_parts); | 63 assert(module_parts); |
85 const size_t kModulePartNumber = 5; | 64 const size_t kModulePartNumber = 5; |
86 FILE* fp = fopen(file.c_str(), "r"); | 65 FILE* fp = fopen(file.c_str(), "r"); |
87 if (fp) { | 66 if (fp) { |
88 char buffer[1024]; | 67 char buffer[1024]; |
89 if (fgets(buffer, sizeof(buffer), fp)) { | 68 if (fgets(buffer, sizeof(buffer), fp)) { |
90 string line(buffer); | 69 string line(buffer); |
91 string::size_type line_break_pos = line.find_first_of('\n'); | 70 string::size_type line_break_pos = line.find_first_of('\n'); |
92 if (line_break_pos == string::npos) { | 71 if (line_break_pos == string::npos) { |
93 assert(0 && "The file is invalid!"); | 72 assert(0 && "The file is invalid!"); |
94 fclose(fp); | 73 fclose(fp); |
95 return false; | 74 return false; |
96 } | 75 } |
97 line.resize(line_break_pos); | 76 line.resize(line_break_pos); |
98 const char kDelimiter = ' '; | 77 const char kDelimiter = ' '; |
99 TokenizeByChar(line, kDelimiter, module_parts); | 78 TokenizeByChar(line, kDelimiter, module_parts); |
100 if (module_parts->size() != kModulePartNumber) | 79 if (module_parts->size() != kModulePartNumber) |
101 module_parts->clear(); | 80 module_parts->clear(); |
102 } | 81 } |
103 fclose(fp); | 82 fclose(fp); |
104 } | 83 } |
105 | 84 |
106 return module_parts->size() == kModulePartNumber; | 85 return module_parts->size() == kModulePartNumber; |
107 } | 86 } |
108 | 87 |
109 //============================================================================= | 88 //============================================================================= |
110 static string CompactIdentifier(const string &uuid) { | 89 string CompactIdentifier(const string &uuid) { |
111 std::vector<string> components; | 90 std::vector<string> components; |
112 TokenizeByChar(uuid, '-', &components); | 91 TokenizeByChar(uuid, '-', &components); |
113 string result; | 92 string result; |
114 for (size_t i = 0; i < components.size(); ++i) | 93 for (size_t i = 0; i < components.size(); ++i) |
115 result += components[i]; | 94 result += components[i]; |
116 return result; | 95 return result; |
117 } | 96 } |
118 | 97 |
119 //============================================================================= | 98 //============================================================================= |
120 static void Start(Options *options) { | 99 void Start(Options *options) { |
121 std::map<string, string> parameters; | 100 std::map<string, string> parameters; |
122 options->success = false; | 101 options->success = false; |
123 std::vector<string> module_parts; | 102 std::vector<string> module_parts; |
124 if (!ModuleDataForSymbolFile(options->symbolsPath, &module_parts)) { | 103 if (!ModuleDataForSymbolFile(options->symbolsPath, &module_parts)) { |
125 fprintf(stderr, "Failed to parse symbol file!\n"); | 104 fprintf(stderr, "Failed to parse symbol file!\n"); |
126 return; | 105 return; |
127 } | 106 } |
128 | 107 |
129 string compacted_id = CompactIdentifier(module_parts[3]); | 108 string compacted_id = CompactIdentifier(module_parts[3]); |
130 | 109 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 } else if (response_code != 200) { | 144 } else if (response_code != 200) { |
166 printf("Failed to send symbol file: Response code %ld\n", response_code); | 145 printf("Failed to send symbol file: Response code %ld\n", response_code); |
167 printf("Response:\n"); | 146 printf("Response:\n"); |
168 printf("%s\n", response.c_str()); | 147 printf("%s\n", response.c_str()); |
169 } else { | 148 } else { |
170 printf("Successfully sent the symbol file.\n"); | 149 printf("Successfully sent the symbol file.\n"); |
171 } | 150 } |
172 options->success = success; | 151 options->success = success; |
173 } | 152 } |
174 | 153 |
175 //============================================================================= | 154 } // namespace sym_upload |
176 static void | 155 } // namespace google_breakpad |
177 Usage(int argc, const char *argv[]) { | |
178 fprintf(stderr, "Submit symbol information.\n"); | |
179 fprintf(stderr, "Usage: %s [options...] <symbols> <upload-URL>\n", argv[0]); | |
180 fprintf(stderr, "Options:\n"); | |
181 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"); | |
183 fprintf(stderr, "-v:\t Version information (e.g., 1.2.3.4)\n"); | |
184 fprintf(stderr, "-x:\t <host[:port]> Use HTTP proxy on given port\n"); | |
185 fprintf(stderr, "-u:\t <user[:password]> Set proxy user and password\n"); | |
186 fprintf(stderr, "-h:\t Usage\n"); | |
187 fprintf(stderr, "-?:\t Usage\n"); | |
188 } | |
189 | |
190 //============================================================================= | |
191 static void | |
192 SetupOptions(int argc, const char *argv[], Options *options) { | |
193 extern int optind; | |
194 int ch; | |
195 | |
196 while ((ch = getopt(argc, (char * const *)argv, "u:v:x:h?")) != -1) { | |
197 switch (ch) { | |
198 case 'h': | |
199 case '?': | |
200 Usage(argc, argv); | |
201 exit(0); | |
202 break; | |
203 case 'u': | |
204 options->proxy_user_pwd = optarg; | |
205 break; | |
206 case 'v': | |
207 options->version = optarg; | |
208 break; | |
209 case 'x': | |
210 options->proxy = optarg; | |
211 break; | |
212 | |
213 default: | |
214 fprintf(stderr, "Invalid option '%c'\n", ch); | |
215 Usage(argc, argv); | |
216 exit(1); | |
217 break; | |
218 } | |
219 } | |
220 | |
221 if ((argc - optind) != 2) { | |
222 fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]); | |
223 Usage(argc, argv); | |
224 exit(1); | |
225 } | |
226 | |
227 options->symbolsPath = argv[optind]; | |
228 options->uploadURLStr = argv[optind + 1]; | |
229 } | |
230 | |
231 //============================================================================= | |
232 int main(int argc, const char* argv[]) { | |
233 Options options; | |
234 SetupOptions(argc, argv, &options); | |
235 Start(&options); | |
236 return options.success ? 0 : 1; | |
237 } | |
OLD | NEW |