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

Side by Side Diff: breakpad/linux/minidump_writer.cc

Issue 113875: Linux: Breakpad updates. (Closed)
Patch Set: ... Created 11 years, 7 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
« no previous file with comments | « breakpad/linux/linux_dumper.cc ('k') | no next file » | 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, Google Inc. 1 // Copyright (c) 2009, 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 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 } 318 }
319 319
320 ~MinidumpWriter() { 320 ~MinidumpWriter() {
321 minidump_writer_.Close(); 321 minidump_writer_.Close();
322 dumper_.ThreadsResume(); 322 dumper_.ThreadsResume();
323 } 323 }
324 324
325 bool Dump() { 325 bool Dump() {
326 // A minidump file contains a number of tagged streams. This is the number 326 // A minidump file contains a number of tagged streams. This is the number
327 // of stream which we write. 327 // of stream which we write.
328 static const unsigned kNumWriters = 10; 328 static const unsigned kNumWriters = 11;
329 329
330 TypedMDRVA<MDRawHeader> header(&minidump_writer_); 330 TypedMDRVA<MDRawHeader> header(&minidump_writer_);
331 TypedMDRVA<MDRawDirectory> dir(&minidump_writer_); 331 TypedMDRVA<MDRawDirectory> dir(&minidump_writer_);
332 if (!header.Allocate()) 332 if (!header.Allocate())
333 return false; 333 return false;
334 if (!dir.AllocateArray(kNumWriters)) 334 if (!dir.AllocateArray(kNumWriters))
335 return false; 335 return false;
336 memset(header.get(), 0, sizeof(MDRawHeader)); 336 memset(header.get(), 0, sizeof(MDRawHeader));
337 337
338 header.get()->signature = MD_HEADER_SIGNATURE; 338 header.get()->signature = MD_HEADER_SIGNATURE;
(...skipping 10 matching lines...) Expand all
349 dir.CopyIndex(dir_index++, &dirent); 349 dir.CopyIndex(dir_index++, &dirent);
350 350
351 if (!WriteMappings(&dirent)) 351 if (!WriteMappings(&dirent))
352 return false; 352 return false;
353 dir.CopyIndex(dir_index++, &dirent); 353 dir.CopyIndex(dir_index++, &dirent);
354 354
355 if (!WriteExceptionStream(&dirent)) 355 if (!WriteExceptionStream(&dirent))
356 return false; 356 return false;
357 dir.CopyIndex(dir_index++, &dirent); 357 dir.CopyIndex(dir_index++, &dirent);
358 358
359 if (!WriteSystemInfoStream(&dirent))
360 return false;
361 dir.CopyIndex(dir_index++, &dirent);
362
359 dirent.stream_type = MD_LINUX_CPU_INFO; 363 dirent.stream_type = MD_LINUX_CPU_INFO;
360 if (!WriteFile(&dirent.location, "/proc/cpuinfo")) 364 if (!WriteFile(&dirent.location, "/proc/cpuinfo"))
361 NullifyDirectoryEntry(&dirent); 365 NullifyDirectoryEntry(&dirent);
362 dir.CopyIndex(dir_index++, &dirent); 366 dir.CopyIndex(dir_index++, &dirent);
363 367
364 dirent.stream_type = MD_LINUX_PROC_STATUS; 368 dirent.stream_type = MD_LINUX_PROC_STATUS;
365 if (!WriteProcFile(&dirent.location, crashing_tid_, "status")) 369 if (!WriteProcFile(&dirent.location, crashing_tid_, "status"))
366 NullifyDirectoryEntry(&dirent); 370 NullifyDirectoryEntry(&dirent);
367 dir.CopyIndex(dir_index++, &dirent); 371 dir.CopyIndex(dir_index++, &dirent);
368 372
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 CPUFillFromThreadInfo(cpu.get(), info); 464 CPUFillFromThreadInfo(cpu.get(), info);
461 thread.thread_context = cpu.location(); 465 thread.thread_context = cpu.location();
462 } 466 }
463 467
464 list.CopyIndexAfterObject(i, &thread, sizeof(thread)); 468 list.CopyIndexAfterObject(i, &thread, sizeof(thread));
465 } 469 }
466 470
467 return true; 471 return true;
468 } 472 }
469 473
474 static bool ShouldIncludeMapping(const MappingInfo& mapping) {
475 if (mapping.name[0] == 0 || // we only want modules with filenames.
476 mapping.offset || // we only want to include one mapping per shared lib.
477 mapping.size < 4096) { // too small to get a signature for.
Lei Zhang 2009/05/27 07:10:55 style nit: two space before //
478 return false;
479 }
480
481 return true;
482 }
483
470 // Write information about the mappings in effect. Because we are using the 484 // Write information about the mappings in effect. Because we are using the
471 // minidump format, the information about the mappings is pretty limited. 485 // minidump format, the information about the mappings is pretty limited.
472 // Because of this, we also include the full, unparsed, /proc/$x/maps file in 486 // Because of this, we also include the full, unparsed, /proc/$x/maps file in
473 // another stream in the file. 487 // another stream in the file.
474 bool WriteMappings(MDRawDirectory* dirent) { 488 bool WriteMappings(MDRawDirectory* dirent) {
475 const unsigned num_mappings = dumper_.mappings().size(); 489 const unsigned num_mappings = dumper_.mappings().size();
490 unsigned num_output_mappings = 0;
491
492 for (unsigned i = 0; i < dumper_.mappings().size(); ++i) {
493 const MappingInfo& mapping = *dumper_.mappings()[i];
494 if (ShouldIncludeMapping(mapping))
495 num_output_mappings++;
496 }
476 497
477 TypedMDRVA<uint32_t> list(&minidump_writer_); 498 TypedMDRVA<uint32_t> list(&minidump_writer_);
478 if (!list.AllocateObjectAndArray(num_mappings, sizeof(MDRawModule))) 499 if (!list.AllocateObjectAndArray(num_output_mappings, sizeof(MDRawModule)))
479 return false; 500 return false;
480 501
481 dirent->stream_type = MD_MODULE_LIST_STREAM; 502 dirent->stream_type = MD_MODULE_LIST_STREAM;
482 dirent->location = list.location(); 503 dirent->location = list.location();
483 *list.get() = num_mappings; 504 *list.get() = num_output_mappings;
484 505
485 for (unsigned i = 0; i < num_mappings; ++i) { 506 for (unsigned i = 0, j = 0; i < num_mappings; ++i) {
486 const MappingInfo& mapping = *dumper_.mappings()[i]; 507 const MappingInfo& mapping = *dumper_.mappings()[i];
508 if (!ShouldIncludeMapping(mapping))
509 continue;
510
487 MDRawModule mod; 511 MDRawModule mod;
488 my_memset(&mod, 0, sizeof(mod)); 512 my_memset(&mod, 0, sizeof(mod));
489 mod.base_of_image = mapping.start_addr; 513 mod.base_of_image = mapping.start_addr;
490 mod.size_of_image = mapping.size; 514 mod.size_of_image = mapping.size;
491 UntypedMDRVA memory(&minidump_writer_); 515 UntypedMDRVA memory(&minidump_writer_);
492 const size_t filename_len = my_strlen(mapping.name); 516 const size_t filename_len = my_strlen(mapping.name);
493 517
518 TypedMDRVA<MDCVInfoPDB70> cv(&minidump_writer_);
519 if (!cv.Allocate())
520 return false;
521 my_memset(cv.get(), 0, sizeof(MDCVInfoPDB70));
522 cv.get()->cv_signature = MD_CVINFOPDB70_SIGNATURE;
523
524 {
525 // We XOR the first page of the file to get a signature for it.
526 uint8_t xor_buf[sizeof(MDGUID)];
527 size_t done = 0;
528 uint8_t* const signature = (uint8_t*) &cv.get()->signature;
529
530 while (done < 4096) {
531 dumper_.CopyFromProcess(xor_buf, crashing_tid_,
532 (void *) (mod.base_of_image + done),
533 sizeof(xor_buf));
534 for (unsigned i = 0; i < sizeof(xor_buf); ++i)
535 signature[i] ^= xor_buf[i];
536 done += sizeof(xor_buf);
537 }
538 }
539
540 mod.cv_record = cv.location();
541
494 if (filename_len) { 542 if (filename_len) {
495 MDLocationDescriptor ld; 543 MDLocationDescriptor ld;
496 if (!minidump_writer_.WriteString(mapping.name, filename_len, &ld)) 544 if (!minidump_writer_.WriteString(mapping.name, filename_len, &ld))
497 return false; 545 return false;
498 mod.module_name_rva = ld.rva; 546 mod.module_name_rva = ld.rva;
499 } 547 }
500 548
501 list.CopyIndexAfterObject(i, &mod, sizeof(mod)); 549 list.CopyIndexAfterObject(j++, &mod, sizeof(mod));
502 } 550 }
503 551
504 return true; 552 return true;
505 } 553 }
506 554
507 bool WriteExceptionStream(MDRawDirectory* dirent) { 555 bool WriteExceptionStream(MDRawDirectory* dirent) {
508 TypedMDRVA<MDRawExceptionStream> exc(&minidump_writer_); 556 TypedMDRVA<MDRawExceptionStream> exc(&minidump_writer_);
509 if (!exc.Allocate()) 557 if (!exc.Allocate())
510 return false; 558 return false;
511 my_memset(exc.get(), 0, sizeof(MDRawExceptionStream)); 559 my_memset(exc.get(), 0, sizeof(MDRawExceptionStream));
512 560
513 dirent->stream_type = MD_EXCEPTION_STREAM; 561 dirent->stream_type = MD_EXCEPTION_STREAM;
514 dirent->location = exc.location(); 562 dirent->location = exc.location();
515 563
516 exc.get()->thread_id = crashing_tid_; 564 exc.get()->thread_id = crashing_tid_;
517 exc.get()->exception_record.exception_code = siginfo_->si_signo; 565 exc.get()->exception_record.exception_code = siginfo_->si_signo;
518 exc.get()->exception_record.exception_address = 566 exc.get()->exception_record.exception_address =
519 (uintptr_t) siginfo_->si_addr; 567 (uintptr_t) siginfo_->si_addr;
520 exc.get()->thread_context = crashing_thread_context_; 568 exc.get()->thread_context = crashing_thread_context_;
521 569
522 return true; 570 return true;
523 } 571 }
524 572
573 bool WriteSystemInfoStream(MDRawDirectory* dirent) {
574 TypedMDRVA<MDRawSystemInfo> si(&minidump_writer_);
575 if (!si.Allocate())
576 return false;
577 my_memset(si.get(), 0, sizeof(MDRawSystemInfo));
578
579 dirent->stream_type = MD_SYSTEM_INFO_STREAM;
580 dirent->location = si.location();
581
582 si.get()->processor_architecture =
583 #if defined(__i386)
584 MD_CPU_ARCHITECTURE_X86;
585 #elif defined(__x86_64)
586 MD_CPU_ARCHITECTURE_AMD64;
587 #endif
588
589 return true;
590 }
591
525 private: 592 private:
526 #if defined(__i386) 593 #if defined(__i386)
527 uintptr_t GetStackPointer() { 594 uintptr_t GetStackPointer() {
528 return ucontext_->uc_mcontext.gregs[REG_ESP]; 595 return ucontext_->uc_mcontext.gregs[REG_ESP];
529 } 596 }
530 #elif defined(__x86_64) 597 #elif defined(__x86_64)
531 uintptr_t GetStackPointer() { 598 uintptr_t GetStackPointer() {
532 return ucontext_->uc_mcontext.gregs[REG_RSP]; 599 return ucontext_->uc_mcontext.gregs[REG_RSP];
533 } 600 }
534 #else 601 #else
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 return false; 669 return false;
603 const ExceptionHandler::CrashContext* context = 670 const ExceptionHandler::CrashContext* context =
604 reinterpret_cast<const ExceptionHandler::CrashContext*>(blob); 671 reinterpret_cast<const ExceptionHandler::CrashContext*>(blob);
605 MinidumpWriter writer(filename, crashing_process, context); 672 MinidumpWriter writer(filename, crashing_process, context);
606 if (!writer.Init()) 673 if (!writer.Init())
607 return false; 674 return false;
608 return writer.Dump(); 675 return writer.Dump();
609 } 676 }
610 677
611 } // namespace google_breakpad 678 } // namespace google_breakpad
OLDNEW
« no previous file with comments | « breakpad/linux/linux_dumper.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698