Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 591 | 591 |
| 592 bool WriteSystemInfoStream(MDRawDirectory* dirent) { | 592 bool WriteSystemInfoStream(MDRawDirectory* dirent) { |
| 593 TypedMDRVA<MDRawSystemInfo> si(&minidump_writer_); | 593 TypedMDRVA<MDRawSystemInfo> si(&minidump_writer_); |
| 594 if (!si.Allocate()) | 594 if (!si.Allocate()) |
| 595 return false; | 595 return false; |
| 596 my_memset(si.get(), 0, sizeof(MDRawSystemInfo)); | 596 my_memset(si.get(), 0, sizeof(MDRawSystemInfo)); |
| 597 | 597 |
| 598 dirent->stream_type = MD_SYSTEM_INFO_STREAM; | 598 dirent->stream_type = MD_SYSTEM_INFO_STREAM; |
| 599 dirent->location = si.location(); | 599 dirent->location = si.location(); |
| 600 | 600 |
| 601 si.get()->processor_architecture = | 601 WriteCPUInformation(si.get()); |
| 602 #if defined(__i386) | |
| 603 MD_CPU_ARCHITECTURE_X86; | |
| 604 #elif defined(__x86_64) | |
| 605 MD_CPU_ARCHITECTURE_AMD64; | |
| 606 #endif | |
| 607 | 602 |
| 608 return true; | 603 return true; |
| 609 } | 604 } |
| 610 | 605 |
| 611 private: | 606 private: |
| 612 #if defined(__i386) | 607 #if defined(__i386) |
| 613 uintptr_t GetStackPointer() { | 608 uintptr_t GetStackPointer() { |
| 614 return ucontext_->uc_mcontext.gregs[REG_ESP]; | 609 return ucontext_->uc_mcontext.gregs[REG_ESP]; |
| 615 } | 610 } |
| 616 #elif defined(__x86_64) | 611 #elif defined(__x86_64) |
| 617 uintptr_t GetStackPointer() { | 612 uintptr_t GetStackPointer() { |
| 618 return ucontext_->uc_mcontext.gregs[REG_RSP]; | 613 return ucontext_->uc_mcontext.gregs[REG_RSP]; |
| 619 } | 614 } |
| 620 #else | 615 #else |
| 621 #error "This code has not been ported to your platform yet." | 616 #error "This code has not been ported to your platform yet." |
| 622 #endif | 617 #endif |
| 623 | 618 |
| 624 void NullifyDirectoryEntry(MDRawDirectory* dirent) { | 619 void NullifyDirectoryEntry(MDRawDirectory* dirent) { |
| 625 dirent->stream_type = 0; | 620 dirent->stream_type = 0; |
| 626 dirent->location.data_size = 0; | 621 dirent->location.data_size = 0; |
| 627 dirent->location.rva = 0; | 622 dirent->location.rva = 0; |
| 628 } | 623 } |
| 629 | 624 |
| 625 bool WriteCPUInformation(MDRawSystemInfo* sys_info) { | |
| 626 char vendor_id[sizeof(sys_info->cpu.x86_cpu_info.vendor_id) + 1] = {0}; | |
| 627 static const char vendor_id_name[] = "vendor_id"; | |
| 628 static const size_t vendor_id_name_length = sizeof(vendor_id_name) - 1; | |
| 629 | |
| 630 struct CpuInfoEntry { | |
| 631 const char* info_name; | |
| 632 int value; | |
| 633 bool found; | |
| 634 } cpu_info_table[] = { | |
| 635 { "processor", -1, false }, | |
| 636 { "model", 0, false }, | |
| 637 { "stepping", 0, false }, | |
| 638 { "cpuid level", 0, false }, | |
| 639 }; | |
| 640 | |
| 641 // processor_architecture should always be set, do this first | |
| 642 sys_info->processor_architecture = | |
| 643 #if defined(__i386) | |
| 644 MD_CPU_ARCHITECTURE_X86; | |
| 645 #elif defined(__x86_64) | |
| 646 MD_CPU_ARCHITECTURE_AMD64; | |
|
agl
2009/06/22 23:26:28
#else
#error "Unknown CPU arch"
<- probably a goo
| |
| 647 #endif | |
| 648 | |
| 649 static const char proc_cpu_path[] = "/proc/cpuinfo"; | |
| 650 FILE* fp = fopen(proc_cpu_path, "r"); | |
| 651 if (!fp) | |
| 652 return false; | |
| 653 | |
| 654 { | |
| 655 char line[128]; | |
| 656 while (fgets(line, sizeof(line), fp)) { | |
| 657 for (size_t i = 0; | |
| 658 i < sizeof(cpu_info_table) / sizeof(cpu_info_table[0]); | |
| 659 i++) { | |
| 660 CpuInfoEntry* entry = &cpu_info_table[i]; | |
| 661 if (entry->found) | |
| 662 continue; | |
| 663 if (!strncmp(line, entry->info_name, strlen(entry->info_name))) { | |
| 664 char* value = strchr(line, ':'); | |
| 665 if (!value) | |
| 666 continue; | |
| 667 | |
| 668 // the above strncmp only matches the prefix, it might be the wrong | |
| 669 // line. i.e. we matched "model name" instead of "model". | |
| 670 // check and make sure there is only spaces between the prefix and | |
| 671 // the colon. | |
| 672 char* space_ptr = line + strlen(entry->info_name); | |
| 673 for (; space_ptr < value; space_ptr++) { | |
| 674 if (!isspace(*space_ptr)) { | |
| 675 break; | |
| 676 } | |
| 677 } | |
| 678 if (space_ptr != value) | |
| 679 continue; | |
| 680 | |
| 681 sscanf(++value, " %d", &(entry->value)); | |
| 682 entry->found = true; | |
| 683 } | |
| 684 } | |
| 685 | |
| 686 // special case for vendor_id | |
| 687 if (!strncmp(line, vendor_id_name, vendor_id_name_length)) { | |
| 688 char* value = strchr(line, ':'); | |
| 689 if (!value) | |
| 690 continue; | |
| 691 | |
| 692 // skip ':" and all the spaces that follows | |
| 693 do { | |
| 694 value++; | |
| 695 } while (isspace(*value)); | |
| 696 | |
| 697 if (*value) { | |
| 698 size_t length = strlen(value); | |
| 699 if (length == 0) | |
| 700 continue; | |
| 701 // we don't want the trailing newline | |
| 702 if (value[length - 1] == '\n') | |
| 703 length--; | |
| 704 // ensure we have space for the value | |
| 705 if (length < sizeof(vendor_id)) | |
| 706 strncpy(vendor_id, value, length); | |
| 707 } | |
| 708 } | |
| 709 } | |
| 710 fclose(fp); | |
| 711 } | |
| 712 | |
| 713 // make sure we got everything we wanted | |
| 714 for (size_t i = 0; | |
| 715 i < sizeof(cpu_info_table) / sizeof(cpu_info_table[0]); | |
| 716 i++) { | |
| 717 if (!cpu_info_table[i].found) { | |
| 718 return false; | |
| 719 } | |
| 720 } | |
| 721 // /proc/cpuinfo contains cpu id, change it into number by adding one. | |
| 722 cpu_info_table[0].value++; | |
| 723 | |
| 724 sys_info->number_of_processors = cpu_info_table[0].value; | |
| 725 sys_info->processor_level = cpu_info_table[3].value; | |
| 726 sys_info->processor_revision = cpu_info_table[1].value << 8 | | |
| 727 cpu_info_table[2].value; | |
| 728 | |
| 729 if (vendor_id[0] != '\0') { | |
| 730 memcpy(sys_info->cpu.x86_cpu_info.vendor_id, vendor_id, | |
| 731 sizeof(sys_info->cpu.x86_cpu_info.vendor_id)); | |
| 732 } | |
| 733 return true; | |
| 734 } | |
| 735 | |
| 630 bool WriteFile(MDLocationDescriptor* result, const char* filename) { | 736 bool WriteFile(MDLocationDescriptor* result, const char* filename) { |
| 631 const int fd = sys_open(filename, O_RDONLY, 0); | 737 const int fd = sys_open(filename, O_RDONLY, 0); |
| 632 if (fd < 0) | 738 if (fd < 0) |
| 633 return false; | 739 return false; |
| 634 | 740 |
| 635 // We can't stat the files because several of the files that we want to | 741 // We can't stat the files because several of the files that we want to |
| 636 // read are kernel seqfiles, which always have a length of zero. So we have | 742 // read are kernel seqfiles, which always have a length of zero. So we have |
| 637 // to read as much as we can into a buffer. | 743 // to read as much as we can into a buffer. |
| 638 static const unsigned kMaxFileSize = 1024; | 744 static const unsigned kMaxFileSize = 1024; |
| 639 uint8_t* data = (uint8_t*) dumper_.allocator()->Alloc(kMaxFileSize); | 745 uint8_t* data = (uint8_t*) dumper_.allocator()->Alloc(kMaxFileSize); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 689 return false; | 795 return false; |
| 690 const ExceptionHandler::CrashContext* context = | 796 const ExceptionHandler::CrashContext* context = |
| 691 reinterpret_cast<const ExceptionHandler::CrashContext*>(blob); | 797 reinterpret_cast<const ExceptionHandler::CrashContext*>(blob); |
| 692 MinidumpWriter writer(filename, crashing_process, context); | 798 MinidumpWriter writer(filename, crashing_process, context); |
| 693 if (!writer.Init()) | 799 if (!writer.Init()) |
| 694 return false; | 800 return false; |
| 695 return writer.Dump(); | 801 return writer.Dump(); |
| 696 } | 802 } |
| 697 | 803 |
| 698 } // namespace google_breakpad | 804 } // namespace google_breakpad |
| OLD | NEW |