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

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

Issue 155653: Include output of "lsb_release -d" in crash reports.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 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/renderer_host/browser_render_process_host.h » ('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 "chrome/app/breakpad_linux.h" 5 #include "chrome/app/breakpad_linux.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <sys/socket.h> 8 #include <sys/socket.h>
9 #include <sys/uio.h> 9 #include <sys/uio.h>
10 #include <unistd.h> 10 #include <unistd.h>
11 11
12 #include <algorithm> 12 #include <algorithm>
13 #include <string> 13 #include <string>
14 14
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/eintr_wrapper.h" 16 #include "base/eintr_wrapper.h"
17 #include "base/file_version_info_linux.h" 17 #include "base/file_version_info_linux.h"
18 #include "base/global_descriptors_posix.h" 18 #include "base/global_descriptors_posix.h"
19 #include "base/linux_util.h"
19 #include "base/path_service.h" 20 #include "base/path_service.h"
20 #include "base/rand_util.h" 21 #include "base/rand_util.h"
21 #include "base/string_util.h" 22 #include "base/string_util.h"
22 #include "breakpad/linux/directory_reader.h" 23 #include "breakpad/linux/directory_reader.h"
23 #include "breakpad/linux/exception_handler.h" 24 #include "breakpad/linux/exception_handler.h"
24 #include "breakpad/linux/linux_libc_support.h" 25 #include "breakpad/linux/linux_libc_support.h"
25 #include "breakpad/linux/linux_syscall_support.h" 26 #include "breakpad/linux/linux_syscall_support.h"
26 #include "breakpad/linux/memory.h" 27 #include "breakpad/linux/memory.h"
27 #include "chrome/common/chrome_switches.h" 28 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/chrome_descriptors.h" 29 #include "chrome/common/chrome_descriptors.h"
29 #include "chrome/installer/util/google_update_settings.h" 30 #include "chrome/installer/util/google_update_settings.h"
30 31
31 static const char kUploadURL[] = 32 static const char kUploadURL[] =
32 "https://clients2.google.com/cr/report"; 33 "https://clients2.google.com/cr/report";
33 34
34 // Writes the value |v| as 16 hex characters to the memory pointed at by 35 // Writes the value |v| as 16 hex characters to the memory pointed at by
35 // |output|. 36 // |output|.
36 static void write_uint64_hex(char* output, uint64_t v) { 37 static void write_uint64_hex(char* output, uint64_t v) {
37 static const char hextable[] = "0123456789abcdef"; 38 static const char hextable[] = "0123456789abcdef";
38 39
39 for (int i = 15; i >= 0; --i) { 40 for (int i = 15; i >= 0; --i) {
40 output[i] = hextable[v & 15]; 41 output[i] = hextable[v & 15];
41 v >>= 4; 42 v >>= 4;
42 } 43 }
43 } 44 }
44 45
45 pid_t UploadCrashDump(const char* filename, 46 pid_t UploadCrashDump(const BreakpadInfo& info) {
46 const char* process_type,
47 unsigned process_type_length,
48 const char* crash_url,
49 unsigned crash_url_length,
50 const char* guid,
51 unsigned guid_length) {
52 // WARNING: this code runs in a compromised context. It may not call into 47 // WARNING: this code runs in a compromised context. It may not call into
53 // libc nor allocate memory normally. 48 // libc nor allocate memory normally.
54 49
55 const int dumpfd = sys_open(filename, O_RDONLY, 0); 50 const int dumpfd = sys_open(info.filename, O_RDONLY, 0);
56 if (dumpfd < 0) { 51 if (dumpfd < 0) {
57 static const char msg[] = "Cannot upload crash dump: failed to open\n"; 52 static const char msg[] = "Cannot upload crash dump: failed to open\n";
58 sys_write(2, msg, sizeof(msg)); 53 sys_write(2, msg, sizeof(msg));
59 return -1; 54 return -1;
60 } 55 }
61 struct kernel_stat st; 56 struct kernel_stat st;
62 if (sys_fstat(dumpfd, &st) != 0) { 57 if (sys_fstat(dumpfd, &st) != 0) {
63 static const char msg[] = "Cannot upload crash dump: stat failed\n"; 58 static const char msg[] = "Cannot upload crash dump: stat failed\n";
64 sys_write(2, msg, sizeof(msg)); 59 sys_write(2, msg, sizeof(msg));
65 sys_close(dumpfd); 60 sys_close(dumpfd);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 // Chrome_Linux \r\n (7, 8) 132 // Chrome_Linux \r\n (7, 8)
138 // BOUNDARY \r\n (9, 10) 133 // BOUNDARY \r\n (9, 10)
139 // Content-Disposition: form-data; name="ver" \r\n \r\n (11..15) 134 // Content-Disposition: form-data; name="ver" \r\n \r\n (11..15)
140 // 1.2.3.4 \r\n (16, 17) 135 // 1.2.3.4 \r\n (16, 17)
141 // BOUNDARY \r\n (18, 19) 136 // BOUNDARY \r\n (18, 19)
142 // Content-Disposition: form-data; name="guid" \r\n \r\n (20..24) 137 // Content-Disposition: form-data; name="guid" \r\n \r\n (20..24)
143 // 1.2.3.4 \r\n (25, 26) 138 // 1.2.3.4 \r\n (25, 26)
144 // BOUNDARY \r\n (27, 28) 139 // BOUNDARY \r\n (27, 28)
145 // 140 //
146 // zero or more: 141 // zero or more:
142 // Content-Disposition: form-data; name="ptype" \r\n \r\n (0..4)
143 // abcdef \r\n (5, 6)
144 // BOUNDARY \r\n (7, 8)
145 //
146 // zero or more:
147 // Content-Disposition: form-data; name="lsb-release" \r\n \r\n (0..4)
148 // abcdef \r\n (5, 6)
149 // BOUNDARY \r\n (7, 8)
150 //
151 // zero or more:
147 // Content-Disposition: form-data; name="url-chunk-1" \r\n \r\n (0..5) 152 // Content-Disposition: form-data; name="url-chunk-1" \r\n \r\n (0..5)
148 // abcdef \r\n (6, 7) 153 // abcdef \r\n (6, 7)
149 // BOUNDARY \r\n (8, 9) 154 // BOUNDARY \r\n (8, 9)
150 // 155 //
151 // Content-Disposition: form-data; name="dump"; filename="dump" \r\n (0,1,2) 156 // Content-Disposition: form-data; name="dump"; filename="dump" \r\n (0,1,2)
152 // Content-Type: application/octet-stream \r\n \r\n (3,4,5) 157 // Content-Type: application/octet-stream \r\n \r\n (3,4,5)
153 // <dump contents> (6) 158 // <dump contents> (6)
154 // \r\n BOUNDARY -- \r\n (7,8,9,10) 159 // \r\n BOUNDARY -- \r\n (7,8,9,10)
155 160
156 static const char rn[] = {'\r', '\n'}; 161 static const char rn[] = {'\r', '\n'};
157 static const char form_data_msg[] = "Content-Disposition: form-data; name=\""; 162 static const char form_data_msg[] = "Content-Disposition: form-data; name=\"";
158 static const char prod_msg[] = "prod"; 163 static const char prod_msg[] = "prod";
159 static const char quote_msg[] = {'"'}; 164 static const char quote_msg[] = {'"'};
160 static const char chrome_linux_msg[] = "Chrome_Linux"; 165 static const char chrome_linux_msg[] = "Chrome_Linux";
161 static const char ver_msg[] = "ver"; 166 static const char ver_msg[] = "ver";
162 static const char guid_msg[] = "guid"; 167 static const char guid_msg[] = "guid";
163 static const char dashdash_msg[] = {'-', '-'}; 168 static const char dashdash_msg[] = {'-', '-'};
164 static const char dump_msg[] = "upload_file_minidump\"; filename=\"dump\""; 169 static const char dump_msg[] = "upload_file_minidump\"; filename=\"dump\"";
165 static const char content_type_msg[] = 170 static const char content_type_msg[] =
166 "Content-Type: application/octet-stream"; 171 "Content-Type: application/octet-stream";
167 static const char url_chunk_msg[] = "url-chunk-"; 172 static const char url_chunk_msg[] = "url-chunk-";
168 static const char process_type_msg[] = "ptype"; 173 static const char process_type_msg[] = "ptype";
174 static const char distro_msg[] = "lsb-release";
169 175
170 struct kernel_iovec iov[29]; 176 struct kernel_iovec iov[29];
171 iov[0].iov_base = mime_boundary; 177 iov[0].iov_base = mime_boundary;
172 iov[0].iov_len = sizeof(mime_boundary) - 1; 178 iov[0].iov_len = sizeof(mime_boundary) - 1;
173 iov[1].iov_base = const_cast<char*>(rn); 179 iov[1].iov_base = const_cast<char*>(rn);
174 iov[1].iov_len = sizeof(rn); 180 iov[1].iov_len = sizeof(rn);
175 181
176 iov[2].iov_base = const_cast<char*>(form_data_msg); 182 iov[2].iov_base = const_cast<char*>(form_data_msg);
177 iov[2].iov_len = sizeof(form_data_msg) - 1; 183 iov[2].iov_len = sizeof(form_data_msg) - 1;
178 iov[3].iov_base = const_cast<char*>(prod_msg); 184 iov[3].iov_base = const_cast<char*>(prod_msg);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 iov[20].iov_len = sizeof(form_data_msg) - 1; 225 iov[20].iov_len = sizeof(form_data_msg) - 1;
220 iov[21].iov_base = const_cast<char*>(guid_msg); 226 iov[21].iov_base = const_cast<char*>(guid_msg);
221 iov[21].iov_len = sizeof(guid_msg) - 1; 227 iov[21].iov_len = sizeof(guid_msg) - 1;
222 iov[22].iov_base = const_cast<char*>(quote_msg); 228 iov[22].iov_base = const_cast<char*>(quote_msg);
223 iov[22].iov_len = sizeof(quote_msg); 229 iov[22].iov_len = sizeof(quote_msg);
224 iov[23].iov_base = const_cast<char*>(rn); 230 iov[23].iov_base = const_cast<char*>(rn);
225 iov[23].iov_len = sizeof(rn); 231 iov[23].iov_len = sizeof(rn);
226 iov[24].iov_base = const_cast<char*>(rn); 232 iov[24].iov_base = const_cast<char*>(rn);
227 iov[24].iov_len = sizeof(rn); 233 iov[24].iov_len = sizeof(rn);
228 234
229 iov[25].iov_base = const_cast<char*>(guid); 235 iov[25].iov_base = const_cast<char*>(info.guid);
230 iov[25].iov_len = guid_length; 236 iov[25].iov_len = info.guid_length;
231 iov[26].iov_base = const_cast<char*>(rn); 237 iov[26].iov_base = const_cast<char*>(rn);
232 iov[26].iov_len = sizeof(rn); 238 iov[26].iov_len = sizeof(rn);
233 239
234 iov[27].iov_base = mime_boundary; 240 iov[27].iov_base = mime_boundary;
235 iov[27].iov_len = sizeof(mime_boundary) - 1; 241 iov[27].iov_len = sizeof(mime_boundary) - 1;
236 iov[28].iov_base = const_cast<char*>(rn); 242 iov[28].iov_base = const_cast<char*>(rn);
237 iov[28].iov_len = sizeof(rn); 243 iov[28].iov_len = sizeof(rn);
238 244
239 sys_writev(fd, iov, 29); 245 sys_writev(fd, iov, 29);
240 246
241 if (process_type_length) { 247 if (info.process_type_length) {
242 iov[0].iov_base = const_cast<char*>(form_data_msg); 248 iov[0].iov_base = const_cast<char*>(form_data_msg);
243 iov[0].iov_len = sizeof(form_data_msg) - 1; 249 iov[0].iov_len = sizeof(form_data_msg) - 1;
244 iov[1].iov_base = const_cast<char*>(process_type_msg); 250 iov[1].iov_base = const_cast<char*>(process_type_msg);
245 iov[1].iov_len = sizeof(process_type_msg) - 1; 251 iov[1].iov_len = sizeof(process_type_msg) - 1;
246 iov[2].iov_base = const_cast<char*>(quote_msg); 252 iov[2].iov_base = const_cast<char*>(quote_msg);
247 iov[2].iov_len = sizeof(quote_msg); 253 iov[2].iov_len = sizeof(quote_msg);
248 iov[3].iov_base = const_cast<char*>(rn); 254 iov[3].iov_base = const_cast<char*>(rn);
249 iov[3].iov_len = sizeof(rn); 255 iov[3].iov_len = sizeof(rn);
250 iov[4].iov_base = const_cast<char*>(rn); 256 iov[4].iov_base = const_cast<char*>(rn);
251 iov[4].iov_len = sizeof(rn); 257 iov[4].iov_len = sizeof(rn);
252 258
253 iov[5].iov_base = const_cast<char*>(process_type); 259 iov[5].iov_base = const_cast<char*>(info.process_type);
254 iov[5].iov_len = process_type_length; 260 iov[5].iov_len = info.process_type_length;
255 iov[6].iov_base = const_cast<char*>(rn); 261 iov[6].iov_base = const_cast<char*>(rn);
256 iov[6].iov_len = sizeof(rn); 262 iov[6].iov_len = sizeof(rn);
257 iov[7].iov_base = mime_boundary; 263 iov[7].iov_base = mime_boundary;
258 iov[7].iov_len = sizeof(mime_boundary) - 1; 264 iov[7].iov_len = sizeof(mime_boundary) - 1;
259 iov[8].iov_base = const_cast<char*>(rn); 265 iov[8].iov_base = const_cast<char*>(rn);
260 iov[8].iov_len = sizeof(rn); 266 iov[8].iov_len = sizeof(rn);
261 267
262 sys_writev(fd, iov, 9); 268 sys_writev(fd, iov, 9);
263 } 269 }
264 270
265 if (crash_url_length) { 271 if (info.distro_length) {
266 unsigned i = 0, done = 0; 272 iov[0].iov_base = const_cast<char*>(form_data_msg);
273 iov[0].iov_len = sizeof(form_data_msg) - 1;
274 iov[1].iov_base = const_cast<char*>(distro_msg);
275 iov[1].iov_len = sizeof(distro_msg) - 1;
276 iov[2].iov_base = const_cast<char*>(quote_msg);
277 iov[2].iov_len = sizeof(quote_msg);
278 iov[3].iov_base = const_cast<char*>(rn);
279 iov[3].iov_len = sizeof(rn);
280 iov[4].iov_base = const_cast<char*>(rn);
281 iov[4].iov_len = sizeof(rn);
282
283 iov[5].iov_base = const_cast<char*>(info.distro);
284 iov[5].iov_len = info.distro_length;
285 iov[6].iov_base = const_cast<char*>(rn);
286 iov[6].iov_len = sizeof(rn);
287 iov[7].iov_base = mime_boundary;
288 iov[7].iov_len = sizeof(mime_boundary) - 1;
289 iov[8].iov_base = const_cast<char*>(rn);
290 iov[8].iov_len = sizeof(rn);
291
292 sys_writev(fd, iov, 9);
293 }
294
295 if (info.crash_url_length) {
296 unsigned i = 0, done = 0, crash_url_length = info.crash_url_length;
267 static const unsigned kMaxCrashChunkSize = 64; 297 static const unsigned kMaxCrashChunkSize = 64;
268 static const unsigned kMaxUrlLength = 8 * kMaxCrashChunkSize; 298 static const unsigned kMaxUrlLength = 8 * kMaxCrashChunkSize;
269 if (crash_url_length > kMaxUrlLength) 299 if (crash_url_length > kMaxUrlLength)
270 crash_url_length = kMaxUrlLength; 300 crash_url_length = kMaxUrlLength;
271 301
272 while (crash_url_length) { 302 while (crash_url_length) {
273 char num[16]; 303 char num[16];
274 const unsigned num_len = my_int_len(++i); 304 const unsigned num_len = my_int_len(++i);
275 my_itos(num, i, num_len); 305 my_itos(num, i, num_len);
276 306
277 iov[0].iov_base = const_cast<char*>(form_data_msg); 307 iov[0].iov_base = const_cast<char*>(form_data_msg);
278 iov[0].iov_len = sizeof(form_data_msg) - 1; 308 iov[0].iov_len = sizeof(form_data_msg) - 1;
279 iov[1].iov_base = const_cast<char*>(url_chunk_msg); 309 iov[1].iov_base = const_cast<char*>(url_chunk_msg);
280 iov[1].iov_len = sizeof(url_chunk_msg) - 1; 310 iov[1].iov_len = sizeof(url_chunk_msg) - 1;
281 iov[2].iov_base = num; 311 iov[2].iov_base = num;
282 iov[2].iov_len = num_len; 312 iov[2].iov_len = num_len;
283 iov[3].iov_base = const_cast<char*>(quote_msg); 313 iov[3].iov_base = const_cast<char*>(quote_msg);
284 iov[3].iov_len = sizeof(quote_msg); 314 iov[3].iov_len = sizeof(quote_msg);
285 iov[4].iov_base = const_cast<char*>(rn); 315 iov[4].iov_base = const_cast<char*>(rn);
286 iov[4].iov_len = sizeof(rn); 316 iov[4].iov_len = sizeof(rn);
287 iov[5].iov_base = const_cast<char*>(rn); 317 iov[5].iov_base = const_cast<char*>(rn);
288 iov[5].iov_len = sizeof(rn); 318 iov[5].iov_len = sizeof(rn);
289 319
290 const unsigned len = crash_url_length > kMaxCrashChunkSize ? 320 const unsigned len = crash_url_length > kMaxCrashChunkSize ?
291 kMaxCrashChunkSize : crash_url_length; 321 kMaxCrashChunkSize : crash_url_length;
292 iov[6].iov_base = const_cast<char*>(crash_url + done); 322 iov[6].iov_base = const_cast<char*>(info.crash_url + done);
293 iov[6].iov_len = len; 323 iov[6].iov_len = len;
294 iov[7].iov_base = const_cast<char*>(rn); 324 iov[7].iov_base = const_cast<char*>(rn);
295 iov[7].iov_len = sizeof(rn); 325 iov[7].iov_len = sizeof(rn);
296 iov[8].iov_base = mime_boundary; 326 iov[8].iov_base = mime_boundary;
297 iov[8].iov_len = sizeof(mime_boundary) - 1; 327 iov[8].iov_len = sizeof(mime_boundary) - 1;
298 iov[9].iov_base = const_cast<char*>(rn); 328 iov[9].iov_base = const_cast<char*>(rn);
299 iov[9].iov_len = sizeof(rn); 329 iov[9].iov_len = sizeof(rn);
300 330
301 sys_writev(fd, iov, 10); 331 sys_writev(fd, iov, 10);
302 332
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 sys_close(fds[1]); 425 sys_close(fds[1]);
396 char id_buf[17]; 426 char id_buf[17];
397 const int len = HANDLE_EINTR(read(fds[0], id_buf, sizeof(id_buf) - 1)); 427 const int len = HANDLE_EINTR(read(fds[0], id_buf, sizeof(id_buf) - 1));
398 if (len > 0) { 428 if (len > 0) {
399 id_buf[len] = 0; 429 id_buf[len] = 0;
400 static const char msg[] = "\nCrash dump id: "; 430 static const char msg[] = "\nCrash dump id: ";
401 sys_write(2, msg, sizeof(msg) - 1); 431 sys_write(2, msg, sizeof(msg) - 1);
402 sys_write(2, id_buf, my_strlen(id_buf)); 432 sys_write(2, id_buf, my_strlen(id_buf));
403 sys_write(2, "\n", 1); 433 sys_write(2, "\n", 1);
404 } 434 }
405 sys_unlink(filename); 435 sys_unlink(info.filename);
406 sys_unlink(buf); 436 sys_unlink(buf);
407 sys__exit(0); 437 sys__exit(0);
408 } 438 }
409 439
410 sys_close(fds[0]); 440 sys_close(fds[0]);
411 sys_dup2(fds[1], 3); 441 sys_dup2(fds[1], 3);
412 static const char* const kWgetBinary = "/usr/bin/wget"; 442 static const char* const kWgetBinary = "/usr/bin/wget";
413 const char* args[] = { 443 const char* args[] = {
414 kWgetBinary, 444 kWgetBinary,
415 header, 445 header,
(...skipping 14 matching lines...) Expand all
430 return child; 460 return child;
431 } 461 }
432 462
433 // This is defined in chrome/browser/google_update_settings_linux.cc, it's the 463 // This is defined in chrome/browser/google_update_settings_linux.cc, it's the
434 // static string containing the user's unique GUID. We send this in the crash 464 // static string containing the user's unique GUID. We send this in the crash
435 // report. 465 // report.
436 namespace google_update { 466 namespace google_update {
437 extern std::string linux_guid; 467 extern std::string linux_guid;
438 } 468 }
439 469
470 // This is defined in base/linux_util.cc, it's the static string containing the
471 // user's distro info. We send this in the crash report.
472 namespace base {
473 extern std::string linux_distro;
474 }
475
440 static bool CrashDone(const char* dump_path, 476 static bool CrashDone(const char* dump_path,
441 const char* minidump_id, 477 const char* minidump_id,
442 void* context, 478 void* context,
443 bool succeeded) { 479 bool succeeded) {
444 // WARNING: this code runs in a compromised context. It may not call into 480 // WARNING: this code runs in a compromised context. It may not call into
445 // libc nor allocate memory normally. 481 // libc nor allocate memory normally.
446 if (!succeeded) 482 if (!succeeded)
447 return false; 483 return false;
448 484
449 google_breakpad::PageAllocator allocator; 485 google_breakpad::PageAllocator allocator;
450 const unsigned dump_path_len = my_strlen(dump_path); 486 const unsigned dump_path_len = my_strlen(dump_path);
451 const unsigned minidump_id_len = my_strlen(minidump_id); 487 const unsigned minidump_id_len = my_strlen(minidump_id);
452 char *const path = reinterpret_cast<char*>(allocator.Alloc( 488 char *const path = reinterpret_cast<char*>(allocator.Alloc(
453 dump_path_len + 1 /* '/' */ + minidump_id_len + 489 dump_path_len + 1 /* '/' */ + minidump_id_len +
454 4 /* ".dmp" */ + 1 /* NUL */)); 490 4 /* ".dmp" */ + 1 /* NUL */));
455 memcpy(path, dump_path, dump_path_len); 491 memcpy(path, dump_path, dump_path_len);
456 path[dump_path_len] = '/'; 492 path[dump_path_len] = '/';
457 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len); 493 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len);
458 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4); 494 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4);
459 path[dump_path_len + 1 + minidump_id_len + 4] = 0; 495 path[dump_path_len + 1 + minidump_id_len + 4] = 0;
460 496
461 UploadCrashDump(path, "browser", 7, NULL, 0, google_update::linux_guid.data(), 497 BreakpadInfo info;
462 google_update::linux_guid.length()); 498 info.filename = path;
499 info.process_type = "browser";
500 info.process_type_length = 7;
501 info.crash_url = NULL;
502 info.crash_url_length = 0;
503 info.guid = google_update::linux_guid.data();
504 info.guid_length = google_update::linux_guid.length();
505 info.distro = base::linux_distro.data();
506 info.distro_length = base::linux_distro.length();
507 UploadCrashDump(info);
463 508
464 return true; 509 return true;
465 } 510 }
466 511
467 void EnableCrashDumping() { 512 void EnableCrashDumping() {
468 // We leak this object. 513 // We leak this object.
469 514
470 new google_breakpad::ExceptionHandler("/tmp", NULL, CrashDone, NULL, 515 new google_breakpad::ExceptionHandler("/tmp", NULL, CrashDone, NULL,
471 true /* install handlers */); 516 true /* install handlers */);
472 } 517 }
473 518
474 // This is defined in chrome/common/child_process_logging_linux.cc, it's the 519 // This is defined in chrome/common/child_process_logging_linux.cc, it's the
475 // static string containing the current active URL. We send this in the crash 520 // static string containing the current active URL. We send this in the crash
476 // report. 521 // report.
477 namespace child_process_logging { 522 namespace child_process_logging {
478 extern std::string active_url; 523 extern std::string active_url;
479 } 524 }
480 525
481 static bool 526 static bool
482 RendererCrashHandler(const void* crash_context, size_t crash_context_size, 527 RendererCrashHandler(const void* crash_context, size_t crash_context_size,
483 void* context) { 528 void* context) {
484 const int fd = (int) context; 529 const int fd = reinterpret_cast<int>(context);
485 int fds[2]; 530 int fds[2];
486 socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 531 socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
487 char guid[kGuidSize] = {0}; 532 char guid[kGuidSize] = {0};
488 char crash_url[kMaxActiveURLSize + 1] = {0}; 533 char crash_url[kMaxActiveURLSize + 1] = {0};
534 char distro[kDistroSize + 1] = {0};
489 const unsigned guid_len = std::min(google_update::linux_guid.size(), 535 const unsigned guid_len = std::min(google_update::linux_guid.size(),
490 kGuidSize); 536 kGuidSize);
491 const unsigned crash_url_len = 537 const unsigned crash_url_len =
492 std::min(child_process_logging::active_url.size(), kMaxActiveURLSize); 538 std::min(child_process_logging::active_url.size(), kMaxActiveURLSize);
539 const unsigned distro_len =
540 std::min(base::linux_distro.size(), kDistroSize);
493 memcpy(guid, google_update::linux_guid.data(), guid_len); 541 memcpy(guid, google_update::linux_guid.data(), guid_len);
494 memcpy(crash_url, child_process_logging::active_url.data(), crash_url_len); 542 memcpy(crash_url, child_process_logging::active_url.data(), crash_url_len);
543 memcpy(distro, base::linux_distro.data(), distro_len);
495 544
496 // The length of the control message: 545 // The length of the control message:
497 static const unsigned kControlMsgSize = CMSG_SPACE(sizeof(int)); 546 static const unsigned kControlMsgSize = CMSG_SPACE(sizeof(int));
498 547
499 struct kernel_msghdr msg; 548 struct kernel_msghdr msg;
500 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); 549 my_memset(&msg, 0, sizeof(struct kernel_msghdr));
501 struct kernel_iovec iov[3]; 550 struct kernel_iovec iov[4];
502 iov[0].iov_base = const_cast<void*>(crash_context); 551 iov[0].iov_base = const_cast<void*>(crash_context);
503 iov[0].iov_len = crash_context_size; 552 iov[0].iov_len = crash_context_size;
504 iov[1].iov_base = guid; 553 iov[1].iov_base = guid;
505 iov[1].iov_len = kGuidSize + 1; 554 iov[1].iov_len = kGuidSize + 1;
506 iov[2].iov_base = crash_url; 555 iov[2].iov_base = crash_url;
507 iov[2].iov_len = kMaxActiveURLSize + 1; 556 iov[2].iov_len = kMaxActiveURLSize + 1;
557 iov[3].iov_base = distro;
558 iov[3].iov_len = kDistroSize + 1;
508 559
509 msg.msg_iov = iov; 560 msg.msg_iov = iov;
510 msg.msg_iovlen = 3; 561 msg.msg_iovlen = 4;
511 char cmsg[kControlMsgSize]; 562 char cmsg[kControlMsgSize];
512 memset(cmsg, 0, kControlMsgSize); 563 memset(cmsg, 0, kControlMsgSize);
513 msg.msg_control = cmsg; 564 msg.msg_control = cmsg;
514 msg.msg_controllen = sizeof(cmsg); 565 msg.msg_controllen = sizeof(cmsg);
515 566
516 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); 567 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
517 hdr->cmsg_level = SOL_SOCKET; 568 hdr->cmsg_level = SOL_SOCKET;
518 hdr->cmsg_type = SCM_RIGHTS; 569 hdr->cmsg_type = SCM_RIGHTS;
519 hdr->cmsg_len = CMSG_LEN(sizeof(int)); 570 hdr->cmsg_len = CMSG_LEN(sizeof(int));
520 *((int*) CMSG_DATA(hdr)) = fds[1]; 571 *((int*) CMSG_DATA(hdr)) = fds[1];
(...skipping 17 matching lines...) Expand all
538 } 589 }
539 590
540 void InitCrashReporter() { 591 void InitCrashReporter() {
541 // Determine the process type and take appropriate action. 592 // Determine the process type and take appropriate action.
542 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); 593 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
543 const std::wstring process_type = 594 const std::wstring process_type =
544 parsed_command_line.GetSwitchValue(switches::kProcessType); 595 parsed_command_line.GetSwitchValue(switches::kProcessType);
545 if (process_type.empty()) { 596 if (process_type.empty()) {
546 if (!GoogleUpdateSettings::GetCollectStatsConsent()) 597 if (!GoogleUpdateSettings::GetCollectStatsConsent())
547 return; 598 return;
599 base::GetLinuxDistro(); // Initialize base::linux_distro if needed.
548 EnableCrashDumping(); 600 EnableCrashDumping();
549 } else if (process_type == switches::kRendererProcess || 601 } else if (process_type == switches::kRendererProcess ||
550 process_type == switches::kZygoteProcess) { 602 process_type == switches::kZygoteProcess) {
551 // We might be chrooted in a zygote or renderer process so we cannot call 603 // We might be chrooted in a zygote or renderer process so we cannot call
552 // GetCollectStatsConsent because that needs access the the user's home 604 // GetCollectStatsConsent because that needs access the the user's home
553 // dir. Instead, we set a command line flag for these processes. 605 // dir. Instead, we set a command line flag for these processes.
554 if (!parsed_command_line.HasSwitch(switches::kRendererCrashDump)) 606 if (!parsed_command_line.HasSwitch(switches::kRendererCrashDump))
555 return; 607 return;
556 google_update::linux_guid = WideToASCII( 608 // Get the guid and linux distro from the command line switch.
609 std::string switch_value = WideToASCII(
557 parsed_command_line.GetSwitchValue(switches::kRendererCrashDump)); 610 parsed_command_line.GetSwitchValue(switches::kRendererCrashDump));
611 size_t separator = switch_value.find(",");
612 if (separator != std::string::npos) {
613 google_update::linux_guid = switch_value.substr(0, separator);
614 base::linux_distro = switch_value.substr(separator + 1);
615 } else {
616 google_update::linux_guid = switch_value;
617 }
558 EnableRendererCrashDumping(); 618 EnableRendererCrashDumping();
559 } 619 }
560 } 620 }
OLDNEW
« no previous file with comments | « chrome/app/breakpad_linux.h ('k') | chrome/browser/renderer_host/browser_render_process_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698