| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 #include <sys/ucontext.h> | 53 #include <sys/ucontext.h> |
| 54 #include <sys/user.h> | 54 #include <sys/user.h> |
| 55 #include <sys/utsname.h> | 55 #include <sys/utsname.h> |
| 56 | 56 |
| 57 #include "client/minidump_file_writer.h" | 57 #include "client/minidump_file_writer.h" |
| 58 #include "google_breakpad/common/minidump_format.h" | 58 #include "google_breakpad/common/minidump_format.h" |
| 59 #include "google_breakpad/common/minidump_cpu_amd64.h" | 59 #include "google_breakpad/common/minidump_cpu_amd64.h" |
| 60 #include "google_breakpad/common/minidump_cpu_x86.h" | 60 #include "google_breakpad/common/minidump_cpu_x86.h" |
| 61 | 61 |
| 62 #include "breakpad/linux/exception_handler.h" | 62 #include "breakpad/linux/exception_handler.h" |
| 63 #include "breakpad/linux/line_reader.h" |
| 63 #include "breakpad/linux/linux_dumper.h" | 64 #include "breakpad/linux/linux_dumper.h" |
| 64 #include "breakpad/linux/linux_libc_support.h" | 65 #include "breakpad/linux/linux_libc_support.h" |
| 65 #include "breakpad/linux/linux_syscall_support.h" | 66 #include "breakpad/linux/linux_syscall_support.h" |
| 66 #include "breakpad/linux/minidump_format_linux.h" | 67 #include "breakpad/linux/minidump_format_linux.h" |
| 67 | 68 |
| 68 // Minidump defines register structures which are different from the raw | 69 // Minidump defines register structures which are different from the raw |
| 69 // structures which we get from the kernel. These are platform specific | 70 // structures which we get from the kernel. These are platform specific |
| 70 // functions to juggle the ucontext and user structures into minidump format. | 71 // functions to juggle the ucontext and user structures into minidump format. |
| 71 #if defined(__i386) | 72 #if defined(__i386) |
| 72 typedef MDRawContextX86 RawContextCPU; | 73 typedef MDRawContextX86 RawContextCPU; |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 // processor_architecture should always be set, do this first | 645 // processor_architecture should always be set, do this first |
| 645 sys_info->processor_architecture = | 646 sys_info->processor_architecture = |
| 646 #if defined(__i386) | 647 #if defined(__i386) |
| 647 MD_CPU_ARCHITECTURE_X86; | 648 MD_CPU_ARCHITECTURE_X86; |
| 648 #elif defined(__x86_64) | 649 #elif defined(__x86_64) |
| 649 MD_CPU_ARCHITECTURE_AMD64; | 650 MD_CPU_ARCHITECTURE_AMD64; |
| 650 #else | 651 #else |
| 651 #error "Unknown CPU arch" | 652 #error "Unknown CPU arch" |
| 652 #endif | 653 #endif |
| 653 | 654 |
| 654 static const char proc_cpu_path[] = "/proc/cpuinfo"; | 655 const int fd = sys_open("/proc/cpuinfo", O_RDONLY, 0); |
| 655 FILE* fp = fopen(proc_cpu_path, "r"); | 656 if (fd < 0) |
| 656 if (!fp) | |
| 657 return false; | 657 return false; |
| 658 | 658 |
| 659 { | 659 { |
| 660 char line[128]; | 660 PageAllocator allocator; |
| 661 while (fgets(line, sizeof(line), fp)) { | 661 LineReader* const line_reader = new(allocator) LineReader(fd); |
| 662 const char* line; |
| 663 unsigned line_len; |
| 664 while (line_reader->GetNextLine(&line, &line_len)) { |
| 662 for (size_t i = 0; | 665 for (size_t i = 0; |
| 663 i < sizeof(cpu_info_table) / sizeof(cpu_info_table[0]); | 666 i < sizeof(cpu_info_table) / sizeof(cpu_info_table[0]); |
| 664 i++) { | 667 i++) { |
| 665 CpuInfoEntry* entry = &cpu_info_table[i]; | 668 CpuInfoEntry* entry = &cpu_info_table[i]; |
| 666 if (entry->found) | 669 if (entry->found) |
| 667 continue; | 670 goto popline; |
| 668 if (!strncmp(line, entry->info_name, strlen(entry->info_name))) { | 671 if (!strncmp(line, entry->info_name, strlen(entry->info_name))) { |
| 669 char* value = strchr(line, ':'); | 672 char* value = strchr(line, ':'); |
| 670 if (!value) | 673 if (!value) |
| 671 continue; | 674 goto popline; |
| 672 | 675 |
| 673 // the above strncmp only matches the prefix, it might be the wrong | 676 // the above strncmp only matches the prefix, it might be the wrong |
| 674 // line. i.e. we matched "model name" instead of "model". | 677 // line. i.e. we matched "model name" instead of "model". |
| 675 // check and make sure there is only spaces between the prefix and | 678 // check and make sure there is only spaces between the prefix and |
| 676 // the colon. | 679 // the colon. |
| 677 char* space_ptr = line + strlen(entry->info_name); | 680 const char* space_ptr = line + strlen(entry->info_name); |
| 678 for (; space_ptr < value; space_ptr++) { | 681 for (; space_ptr < value; space_ptr++) { |
| 679 if (!isspace(*space_ptr)) { | 682 if (!isspace(*space_ptr)) { |
| 680 break; | 683 break; |
| 681 } | 684 } |
| 682 } | 685 } |
| 683 if (space_ptr != value) | 686 if (space_ptr != value) |
| 684 continue; | 687 goto popline; |
| 685 | 688 |
| 686 sscanf(++value, " %d", &(entry->value)); | 689 sscanf(++value, " %d", &(entry->value)); |
| 687 entry->found = true; | 690 entry->found = true; |
| 688 } | 691 } |
| 689 } | 692 } |
| 690 | 693 |
| 691 // special case for vendor_id | 694 // special case for vendor_id |
| 692 if (!strncmp(line, vendor_id_name, vendor_id_name_length)) { | 695 if (!strncmp(line, vendor_id_name, vendor_id_name_length)) { |
| 693 char* value = strchr(line, ':'); | 696 char* value = strchr(line, ':'); |
| 694 if (!value) | 697 if (!value) |
| 695 continue; | 698 goto popline; |
| 696 | 699 |
| 697 // skip ':" and all the spaces that follows | 700 // skip ':" and all the spaces that follows |
| 698 do { | 701 do { |
| 699 value++; | 702 value++; |
| 700 } while (isspace(*value)); | 703 } while (isspace(*value)); |
| 701 | 704 |
| 702 if (*value) { | 705 if (*value) { |
| 703 size_t length = strlen(value); | 706 size_t length = strlen(value); |
| 704 if (length == 0) | 707 if (length == 0) |
| 705 continue; | 708 goto popline; |
| 706 // we don't want the trailing newline | 709 // we don't want the trailing newline |
| 707 if (value[length - 1] == '\n') | 710 if (value[length - 1] == '\n') |
| 708 length--; | 711 length--; |
| 709 // ensure we have space for the value | 712 // ensure we have space for the value |
| 710 if (length < sizeof(vendor_id)) | 713 if (length < sizeof(vendor_id)) |
| 711 strncpy(vendor_id, value, length); | 714 strncpy(vendor_id, value, length); |
| 712 } | 715 } |
| 713 } | 716 } |
| 717 |
| 718 popline: |
| 719 line_reader->PopLine(line_len); |
| 714 } | 720 } |
| 715 fclose(fp); | 721 sys_close(fd); |
| 716 } | 722 } |
| 717 | 723 |
| 718 // make sure we got everything we wanted | 724 // make sure we got everything we wanted |
| 719 for (size_t i = 0; | 725 for (size_t i = 0; |
| 720 i < sizeof(cpu_info_table) / sizeof(cpu_info_table[0]); | 726 i < sizeof(cpu_info_table) / sizeof(cpu_info_table[0]); |
| 721 i++) { | 727 i++) { |
| 722 if (!cpu_info_table[i].found) { | 728 if (!cpu_info_table[i].found) { |
| 723 return false; | 729 return false; |
| 724 } | 730 } |
| 725 } | 731 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 return false; | 852 return false; |
| 847 const ExceptionHandler::CrashContext* context = | 853 const ExceptionHandler::CrashContext* context = |
| 848 reinterpret_cast<const ExceptionHandler::CrashContext*>(blob); | 854 reinterpret_cast<const ExceptionHandler::CrashContext*>(blob); |
| 849 MinidumpWriter writer(filename, crashing_process, context); | 855 MinidumpWriter writer(filename, crashing_process, context); |
| 850 if (!writer.Init()) | 856 if (!writer.Init()) |
| 851 return false; | 857 return false; |
| 852 return writer.Dump(); | 858 return writer.Dump(); |
| 853 } | 859 } |
| 854 | 860 |
| 855 } // namespace google_breakpad | 861 } // namespace google_breakpad |
| OLD | NEW |