Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: chrome/app/breakpad_linux.cc

Issue 118096: Generate GUIDs for users who wish to upload crash reports. Include it in cra... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/app/breakpad_linux.h ('k') | chrome/browser/google_update_settings_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <fcntl.h> 5 #include <fcntl.h>
6 #include <sys/socket.h> 6 #include <sys/socket.h>
7 #include <sys/uio.h> 7 #include <sys/uio.h>
8 #include <unistd.h> 8 #include <unistd.h>
9 9
10 #include <string> 10 #include <string>
(...skipping 18 matching lines...) Expand all
29 // |output|. 29 // |output|.
30 static void write_uint64_hex(char* output, uint64_t v) { 30 static void write_uint64_hex(char* output, uint64_t v) {
31 static const char hextable[] = "0123456789abcdef"; 31 static const char hextable[] = "0123456789abcdef";
32 32
33 for (int i = 15; i >= 0; --i) { 33 for (int i = 15; i >= 0; --i) {
34 output[i] = hextable[v & 15]; 34 output[i] = hextable[v & 15];
35 v >>= 4; 35 v >>= 4;
36 } 36 }
37 } 37 }
38 38
39 pid_t UploadCrashDump(const char* filename, const char* crash_url, 39 pid_t UploadCrashDump(const char* filename,
40 unsigned crash_url_length) { 40 const char* crash_url,
41 unsigned crash_url_length,
42 const char* guid,
43 unsigned guid_length) {
41 // WARNING: this code runs in a compromised context. It may not call into 44 // WARNING: this code runs in a compromised context. It may not call into
42 // libc nor allocate memory normally. 45 // libc nor allocate memory normally.
43 46
44 const int dumpfd = sys_open(filename, O_RDONLY, 0); 47 const int dumpfd = sys_open(filename, O_RDONLY, 0);
45 if (dumpfd < 0) { 48 if (dumpfd < 0) {
46 static const char msg[] = "Cannot upload crash dump: failed to open\n"; 49 static const char msg[] = "Cannot upload crash dump: failed to open\n";
47 sys_write(2, msg, sizeof(msg)); 50 sys_write(2, msg, sizeof(msg));
48 return -1; 51 return -1;
49 } 52 }
50 struct kernel_stat st; 53 struct kernel_stat st;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 version_msg[i] = static_cast<char>(version[i]); 124 version_msg[i] = static_cast<char>(version[i]);
122 125
123 // The MIME block looks like this: 126 // The MIME block looks like this:
124 // BOUNDARY \r\n (0, 1) 127 // BOUNDARY \r\n (0, 1)
125 // Content-Disposition: form-data; name="prod" \r\n \r\n (2..6) 128 // Content-Disposition: form-data; name="prod" \r\n \r\n (2..6)
126 // Chrome_Linux \r\n (7, 8) 129 // Chrome_Linux \r\n (7, 8)
127 // BOUNDARY \r\n (9, 10) 130 // BOUNDARY \r\n (9, 10)
128 // Content-Disposition: form-data; name="ver" \r\n \r\n (11..15) 131 // Content-Disposition: form-data; name="ver" \r\n \r\n (11..15)
129 // 1.2.3.4 \r\n (16, 17) 132 // 1.2.3.4 \r\n (16, 17)
130 // BOUNDARY \r\n (18, 19) 133 // BOUNDARY \r\n (18, 19)
134 // Content-Disposition: form-data; name="guid" \r\n \r\n (20..24)
135 // 1.2.3.4 \r\n (25, 26)
136 // BOUNDARY \r\n (27, 28)
131 // 137 //
132 // zero or more: 138 // zero or more:
133 // Content-Disposition: form-data; name="url-chunk-1" \r\n \r\n (0..5) 139 // Content-Disposition: form-data; name="url-chunk-1" \r\n \r\n (0..5)
134 // abcdef \r\n (6, 7) 140 // abcdef \r\n (6, 7)
135 // BOUNDARY \r\n (8, 9) 141 // BOUNDARY \r\n (8, 9)
136 // 142 //
137 // Content-Disposition: form-data; name="dump"; filename="dump" \r\n (0,1,2) 143 // Content-Disposition: form-data; name="dump"; filename="dump" \r\n (0,1,2)
138 // Content-Type: application/octet-stream \r\n \r\n (3,4,5) 144 // Content-Type: application/octet-stream \r\n \r\n (3,4,5)
139 // <dump contents> (6) 145 // <dump contents> (6)
140 // \r\n BOUNDARY -- \r\n (7,8,9,10) 146 // \r\n BOUNDARY -- \r\n (7,8,9,10)
141 147
142 static const char rn[] = {'\r', '\n'}; 148 static const char rn[] = {'\r', '\n'};
143 static const char form_data_msg[] = "Content-Disposition: form-data; name=\""; 149 static const char form_data_msg[] = "Content-Disposition: form-data; name=\"";
144 static const char prod_msg[] = "prod"; 150 static const char prod_msg[] = "prod";
145 static const char quote_msg[] = {'"'}; 151 static const char quote_msg[] = {'"'};
146 static const char chrome_linux_msg[] = "Chrome_Linux"; 152 static const char chrome_linux_msg[] = "Chrome_Linux";
147 static const char ver_msg[] = "ver"; 153 static const char ver_msg[] = "ver";
154 static const char guid_msg[] = "guid";
148 static const char dashdash_msg[] = {'-', '-'}; 155 static const char dashdash_msg[] = {'-', '-'};
149 static const char dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; 156 static const char dump_msg[] = "upload_file_minidump\"; filename=\"dump\"";
150 static const char content_type_msg[] = 157 static const char content_type_msg[] =
151 "Content-Type: application/octet-stream"; 158 "Content-Type: application/octet-stream";
152 static const char url_chunk_msg[] = "url-chunk-"; 159 static const char url_chunk_msg[] = "url-chunk-";
153 160
154 struct kernel_iovec iov[20]; 161 struct kernel_iovec iov[29];
155 iov[0].iov_base = mime_boundary; 162 iov[0].iov_base = mime_boundary;
156 iov[0].iov_len = sizeof(mime_boundary) - 1; 163 iov[0].iov_len = sizeof(mime_boundary) - 1;
157 iov[1].iov_base = const_cast<char*>(rn); 164 iov[1].iov_base = const_cast<char*>(rn);
158 iov[1].iov_len = sizeof(rn); 165 iov[1].iov_len = sizeof(rn);
159 166
160 iov[2].iov_base = const_cast<char*>(form_data_msg); 167 iov[2].iov_base = const_cast<char*>(form_data_msg);
161 iov[2].iov_len = sizeof(form_data_msg) - 1; 168 iov[2].iov_len = sizeof(form_data_msg) - 1;
162 iov[3].iov_base = const_cast<char*>(prod_msg); 169 iov[3].iov_base = const_cast<char*>(prod_msg);
163 iov[3].iov_len = sizeof(prod_msg) - 1; 170 iov[3].iov_len = sizeof(prod_msg) - 1;
164 iov[4].iov_base = const_cast<char*>(quote_msg); 171 iov[4].iov_base = const_cast<char*>(quote_msg);
(...skipping 27 matching lines...) Expand all
192 iov[16].iov_base = const_cast<char*>(version_msg); 199 iov[16].iov_base = const_cast<char*>(version_msg);
193 iov[16].iov_len = sizeof(version_msg) - 1; 200 iov[16].iov_len = sizeof(version_msg) - 1;
194 iov[17].iov_base = const_cast<char*>(rn); 201 iov[17].iov_base = const_cast<char*>(rn);
195 iov[17].iov_len = sizeof(rn); 202 iov[17].iov_len = sizeof(rn);
196 203
197 iov[18].iov_base = mime_boundary; 204 iov[18].iov_base = mime_boundary;
198 iov[18].iov_len = sizeof(mime_boundary) - 1; 205 iov[18].iov_len = sizeof(mime_boundary) - 1;
199 iov[19].iov_base = const_cast<char*>(rn); 206 iov[19].iov_base = const_cast<char*>(rn);
200 iov[19].iov_len = sizeof(rn); 207 iov[19].iov_len = sizeof(rn);
201 208
202 sys_writev(fd, iov, 20); 209 iov[20].iov_base = const_cast<char*>(form_data_msg);
210 iov[20].iov_len = sizeof(form_data_msg) - 1;
211 iov[21].iov_base = const_cast<char*>(guid_msg);
212 iov[21].iov_len = sizeof(guid_msg) - 1;
213 iov[22].iov_base = const_cast<char*>(quote_msg);
214 iov[22].iov_len = sizeof(quote_msg);
215 iov[23].iov_base = const_cast<char*>(rn);
216 iov[23].iov_len = sizeof(rn);
217 iov[24].iov_base = const_cast<char*>(rn);
218 iov[24].iov_len = sizeof(rn);
219
220 iov[25].iov_base = const_cast<char*>(guid);
221 iov[25].iov_len = guid_length;
222 iov[26].iov_base = const_cast<char*>(rn);
223 iov[26].iov_len = sizeof(rn);
224
225 iov[27].iov_base = mime_boundary;
226 iov[27].iov_len = sizeof(mime_boundary) - 1;
227 iov[28].iov_base = const_cast<char*>(rn);
228 iov[28].iov_len = sizeof(rn);
229
230 sys_writev(fd, iov, 29);
203 231
204 if (crash_url_length) { 232 if (crash_url_length) {
205 unsigned i = 0, done = 0; 233 unsigned i = 0, done = 0;
206 static const unsigned kMaxCrashChunkSize = 64; 234 static const unsigned kMaxCrashChunkSize = 64;
207 static const unsigned kMaxUrlLength = 8 * kMaxCrashChunkSize; 235 static const unsigned kMaxUrlLength = 8 * kMaxCrashChunkSize;
208 if (crash_url_length > kMaxUrlLength) 236 if (crash_url_length > kMaxUrlLength)
209 crash_url_length = kMaxUrlLength; 237 crash_url_length = kMaxUrlLength;
210 238
211 while (crash_url_length) { 239 while (crash_url_length) {
212 char num[16]; 240 char num[16];
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 359
332 const pid_t child = sys_fork(); 360 const pid_t child = sys_fork();
333 if (child) { 361 if (child) {
334 sys_close(fds[1]); 362 sys_close(fds[1]);
335 char id_buf[17]; 363 char id_buf[17];
336 const int len = HANDLE_EINTR(read(fds[0], id_buf, sizeof(id_buf) - 1)); 364 const int len = HANDLE_EINTR(read(fds[0], id_buf, sizeof(id_buf) - 1));
337 if (len > 0) { 365 if (len > 0) {
338 id_buf[len] = 0; 366 id_buf[len] = 0;
339 static const char msg[] = "\nCrash dump id: "; 367 static const char msg[] = "\nCrash dump id: ";
340 sys_write(2, msg, sizeof(msg) - 1); 368 sys_write(2, msg, sizeof(msg) - 1);
341 sys_write(2, id_buf, my_strlen(buf)); 369 sys_write(2, id_buf, my_strlen(id_buf));
342 sys_write(2, "\n", 1); 370 sys_write(2, "\n", 1);
343 } 371 }
344 sys_unlink(filename); 372 sys_unlink(filename);
345 sys_unlink(buf); 373 sys_unlink(buf);
346 sys__exit(0); 374 sys__exit(0);
347 } 375 }
348 376
349 sys_close(fds[0]); 377 sys_close(fds[0]);
350 sys_dup2(fds[1], 3); 378 sys_dup2(fds[1], 3);
351 static const char* const kWgetBinary = "/usr/bin/wget"; 379 static const char* const kWgetBinary = "/usr/bin/wget";
(...skipping 10 matching lines...) Expand all
362 execv("/usr/bin/wget", const_cast<char**>(args)); 390 execv("/usr/bin/wget", const_cast<char**>(args));
363 static const char msg[] = "Cannot upload crash dump: cannot exec " 391 static const char msg[] = "Cannot upload crash dump: cannot exec "
364 "/usr/bin/wget\n"; 392 "/usr/bin/wget\n";
365 sys_write(2, msg, sizeof(msg) - 1); 393 sys_write(2, msg, sizeof(msg) - 1);
366 sys__exit(1); 394 sys__exit(1);
367 } 395 }
368 396
369 return child; 397 return child;
370 } 398 }
371 399
400 // This is defined in chrome/browser/google_update_settings_linux.cc, it's the
401 // static string containing the user's unique GUID. We send this in the crash
402 // report.
403 namespace google_update {
404 extern std::string linux_guid;
405 }
406
372 static bool CrashDone(const char* dump_path, 407 static bool CrashDone(const char* dump_path,
373 const char* minidump_id, 408 const char* minidump_id,
374 void* context, 409 void* context,
375 bool succeeded) { 410 bool succeeded) {
376 // WARNING: this code runs in a compromised context. It may not call into 411 // WARNING: this code runs in a compromised context. It may not call into
377 // libc nor allocate memory normally. 412 // libc nor allocate memory normally.
378 if (!succeeded) 413 if (!succeeded)
379 return false; 414 return false;
380 415
381 google_breakpad::PageAllocator allocator; 416 google_breakpad::PageAllocator allocator;
382 const unsigned dump_path_len = my_strlen(dump_path); 417 const unsigned dump_path_len = my_strlen(dump_path);
383 const unsigned minidump_id_len = my_strlen(minidump_id); 418 const unsigned minidump_id_len = my_strlen(minidump_id);
384 char *const path = reinterpret_cast<char*>(allocator.Alloc( 419 char *const path = reinterpret_cast<char*>(allocator.Alloc(
385 dump_path_len + 1 /* '/' */ + minidump_id_len + 420 dump_path_len + 1 /* '/' */ + minidump_id_len +
386 4 /* ".dmp" */ + 1 /* NUL */)); 421 4 /* ".dmp" */ + 1 /* NUL */));
387 memcpy(path, dump_path, dump_path_len); 422 memcpy(path, dump_path, dump_path_len);
388 path[dump_path_len] = '/'; 423 path[dump_path_len] = '/';
389 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len); 424 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len);
390 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4); 425 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4);
391 path[dump_path_len + 1 + minidump_id_len + 4] = 0; 426 path[dump_path_len + 1 + minidump_id_len + 4] = 0;
392 427
393 UploadCrashDump(path, NULL, 0); 428 UploadCrashDump(path, NULL, 0, google_update::linux_guid.data(),
429 google_update::linux_guid.length());
394 430
395 return true; 431 return true;
396 } 432 }
397 433
398 void EnableCrashDumping() { 434 void EnableCrashDumping() {
399 // We leak this object. 435 // We leak this object.
400 436
401 new google_breakpad::ExceptionHandler("/tmp", NULL, CrashDone, NULL, 437 new google_breakpad::ExceptionHandler("/tmp", NULL, CrashDone, NULL,
402 true /* install handlers */); 438 true /* install handlers */);
403 } 439 }
(...skipping 14 matching lines...) Expand all
418 454
419 // The length of the control message: 455 // The length of the control message:
420 static const unsigned kControlMsgSize = 456 static const unsigned kControlMsgSize =
421 CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred)); 457 CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred));
422 458
423 union { 459 union {
424 struct kernel_msghdr msg; 460 struct kernel_msghdr msg;
425 struct msghdr sys_msg; 461 struct msghdr sys_msg;
426 }; 462 };
427 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); 463 my_memset(&msg, 0, sizeof(struct kernel_msghdr));
428 struct kernel_iovec iov[2]; 464 struct kernel_iovec iov[3];
429 iov[0].iov_base = const_cast<void*>(crash_context); 465 iov[0].iov_base = const_cast<void*>(crash_context);
430 iov[0].iov_len = crash_context_size; 466 iov[0].iov_len = crash_context_size;
431 iov[1].iov_base = const_cast<char*>(renderer_logging::active_url.data()); 467 iov[1].iov_base = const_cast<char*>(google_update::linux_guid.data());
432 iov[1].iov_len = renderer_logging::active_url.size(); 468 iov[1].iov_len = google_update::linux_guid.size();
469 iov[2].iov_base = const_cast<char*>(renderer_logging::active_url.data());
470 iov[2].iov_len = renderer_logging::active_url.size();
433 471
434 msg.msg_iov = iov; 472 msg.msg_iov = iov;
435 msg.msg_iovlen = 2; 473 msg.msg_iovlen = 3;
436 char cmsg[kControlMsgSize]; 474 char cmsg[kControlMsgSize];
437 memset(cmsg, 0, kControlMsgSize); 475 memset(cmsg, 0, kControlMsgSize);
438 msg.msg_control = cmsg; 476 msg.msg_control = cmsg;
439 msg.msg_controllen = sizeof(cmsg); 477 msg.msg_controllen = sizeof(cmsg);
440 478
441 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); 479 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
442 hdr->cmsg_level = SOL_SOCKET; 480 hdr->cmsg_level = SOL_SOCKET;
443 hdr->cmsg_type = SCM_RIGHTS; 481 hdr->cmsg_type = SCM_RIGHTS;
444 hdr->cmsg_len = CMSG_LEN(sizeof(int)); 482 hdr->cmsg_len = CMSG_LEN(sizeof(int));
445 *((int*) CMSG_DATA(hdr)) = fds[1]; 483 *((int*) CMSG_DATA(hdr)) = fds[1];
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 517
480 // Determine the process type and take appropriate action. 518 // Determine the process type and take appropriate action.
481 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); 519 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
482 const std::wstring process_type = 520 const std::wstring process_type =
483 parsed_command_line.GetSwitchValue(switches::kProcessType); 521 parsed_command_line.GetSwitchValue(switches::kProcessType);
484 if (process_type.empty()) 522 if (process_type.empty())
485 EnableCrashDumping(); 523 EnableCrashDumping();
486 else if (process_type == switches::kRendererProcess) 524 else if (process_type == switches::kRendererProcess)
487 EnableRendererCrashDumping(); 525 EnableRendererCrashDumping();
488 } 526 }
OLDNEW
« no previous file with comments | « chrome/app/breakpad_linux.h ('k') | chrome/browser/google_update_settings_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698