OLD | NEW |
1 // Copyright (c) 2010 Google Inc. | 1 // Copyright (c) 2010 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #define PRIx32 "lx" | 48 #define PRIx32 "lx" |
49 #define snprintf _snprintf | 49 #define snprintf _snprintf |
50 #else // _WIN32 | 50 #else // _WIN32 |
51 #include <unistd.h> | 51 #include <unistd.h> |
52 #endif // _WIN32 | 52 #endif // _WIN32 |
53 | 53 |
54 #include <fstream> | 54 #include <fstream> |
55 #include <iostream> | 55 #include <iostream> |
56 #include <limits> | 56 #include <limits> |
57 #include <map> | 57 #include <map> |
| 58 #include <sstream> |
58 #include <vector> | 59 #include <vector> |
59 | 60 |
60 #include "processor/range_map-inl.h" | 61 #include "processor/range_map-inl.h" |
61 | 62 |
62 #include "common/scoped_ptr.h" | 63 #include "common/scoped_ptr.h" |
63 #include "google_breakpad/processor/dump_context.h" | 64 #include "google_breakpad/processor/dump_context.h" |
64 #include "processor/basic_code_module.h" | 65 #include "processor/basic_code_module.h" |
65 #include "processor/basic_code_modules.h" | 66 #include "processor/basic_code_modules.h" |
66 #include "processor/logging.h" | 67 #include "processor/logging.h" |
67 | 68 |
68 namespace google_breakpad { | 69 namespace google_breakpad { |
69 | 70 |
70 | 71 |
71 using std::istream; | 72 using std::istream; |
72 using std::ifstream; | 73 using std::ifstream; |
73 using std::numeric_limits; | 74 using std::numeric_limits; |
| 75 using std::stringstream; |
74 using std::vector; | 76 using std::vector; |
75 | 77 |
76 // Returns true iff |context_size| matches exactly one of the sizes of the | 78 // Returns true iff |context_size| matches exactly one of the sizes of the |
77 // various MDRawContext* types. | 79 // various MDRawContext* types. |
78 // TODO(blundell): This function can be removed once | 80 // TODO(blundell): This function can be removed once |
79 // http://code.google.com/p/google-breakpad/issues/detail?id=550 is fixed. | 81 // http://code.google.com/p/google-breakpad/issues/detail?id=550 is fixed. |
80 static bool IsContextSizeUnique(uint32_t context_size) { | 82 static bool IsContextSizeUnique(uint32_t context_size) { |
81 int num_matching_contexts = 0; | 83 int num_matching_contexts = 0; |
82 if (context_size == sizeof(MDRawContextX86)) | 84 if (context_size == sizeof(MDRawContextX86)) |
83 num_matching_contexts++; | 85 num_matching_contexts++; |
(...skipping 3881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3965 | 3967 |
3966 for (unsigned int info_index = 0; | 3968 for (unsigned int info_index = 0; |
3967 info_index < info_count_; | 3969 info_index < info_count_; |
3968 ++info_index) { | 3970 ++info_index) { |
3969 printf("info[%d]\n", info_index); | 3971 printf("info[%d]\n", info_index); |
3970 (*infos_)[info_index].Print(); | 3972 (*infos_)[info_index].Print(); |
3971 printf("\n"); | 3973 printf("\n"); |
3972 } | 3974 } |
3973 } | 3975 } |
3974 | 3976 |
| 3977 // |
| 3978 // MinidumpLinuxMaps |
| 3979 // |
| 3980 |
| 3981 MinidumpLinuxMaps::MinidumpLinuxMaps(Minidump *minidump) |
| 3982 : MinidumpObject(minidump) { |
| 3983 } |
| 3984 |
| 3985 void MinidumpLinuxMaps::Print() { |
| 3986 if (!valid_) { |
| 3987 BPLOG(ERROR) << "MinidumpLinuxMaps cannot print invalid data"; |
| 3988 return; |
| 3989 } |
| 3990 std::cout << GetPathname() << std::endl; |
| 3991 } |
| 3992 |
| 3993 // |
| 3994 // MinidumpLinuxMapsList |
| 3995 // |
| 3996 |
| 3997 MinidumpLinuxMapsList::MinidumpLinuxMapsList(Minidump *minidump) |
| 3998 : MinidumpStream(minidump), |
| 3999 maps_(NULL), |
| 4000 maps_count_(0) { |
| 4001 } |
| 4002 |
| 4003 MinidumpLinuxMapsList::~MinidumpLinuxMapsList() { |
| 4004 for (unsigned int i = 0; i < maps_->size(); i++) { |
| 4005 delete (*maps_)[i]; |
| 4006 } |
| 4007 delete maps_; |
| 4008 } |
| 4009 |
| 4010 const MinidumpLinuxMaps *MinidumpLinuxMapsList::GetLinuxMapsForAddress( |
| 4011 uint64_t address) const { |
| 4012 if (!valid_) { |
| 4013 BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsForAddress"; |
| 4014 return NULL; |
| 4015 } |
| 4016 |
| 4017 // Search every memory mapping. |
| 4018 for (unsigned int index = 0; index < maps_count_; index++) { |
| 4019 // Check if address is within bounds of the current memory region. |
| 4020 if ((*maps_)[index]->GetBase() <= address && |
| 4021 (*maps_)[index]->GetBase() + (*maps_)[index]->GetSize() > address) { |
| 4022 return (*maps_)[index]; |
| 4023 } |
| 4024 } |
| 4025 |
| 4026 // No mapping encloses the memory address. |
| 4027 BPLOG(ERROR) << "MinidumpLinuxMapsList has no mapping at " |
| 4028 << HexString(address); |
| 4029 return NULL; |
| 4030 } |
| 4031 |
| 4032 const MinidumpLinuxMaps *MinidumpLinuxMapsList::GetLinuxMapsAtIndex( |
| 4033 unsigned int index) const { |
| 4034 if (!valid_) { |
| 4035 BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsAtIndex"; |
| 4036 return NULL; |
| 4037 } |
| 4038 |
| 4039 // Index out of bounds. |
| 4040 if (index >= maps_count_) { |
| 4041 BPLOG(ERROR) << "MinidumpLinuxMapsList index of out range: " |
| 4042 << index |
| 4043 << "/" |
| 4044 << maps_count_; |
| 4045 return NULL; |
| 4046 } |
| 4047 return (*maps_)[index]; |
| 4048 } |
| 4049 |
| 4050 bool MinidumpLinuxMapsList::Read(uint32_t expected_size) { |
| 4051 // Invalidate cached data. |
| 4052 delete maps_; |
| 4053 maps_ = NULL; |
| 4054 maps_count_ = 0; |
| 4055 |
| 4056 valid_ = false; |
| 4057 |
| 4058 // Load and check expected stream length. |
| 4059 uint32_t length = 0; |
| 4060 if (!minidump_->SeekToStreamType(MD_LINUX_MAPS, &length)) { |
| 4061 BPLOG(ERROR) << "MinidumpLinuxMapsList stream type not found"; |
| 4062 return false; |
| 4063 } |
| 4064 if (expected_size != length) { |
| 4065 BPLOG(ERROR) << "MinidumpLinuxMapsList size mismatch: " |
| 4066 << expected_size |
| 4067 << " != " |
| 4068 << length; |
| 4069 return false; |
| 4070 } |
| 4071 |
| 4072 // Create a vector to read stream data. The vector needs to have |
| 4073 // at least enough capacity to read all the data. |
| 4074 vector<char> mapping_bytes(length); |
| 4075 if (!minidump_->ReadBytes(&mapping_bytes[0], length)) { |
| 4076 BPLOG(ERROR) << "MinidumpLinuxMapsList failed to read bytes"; |
| 4077 return false; |
| 4078 } |
| 4079 string map_string(mapping_bytes.begin(), mapping_bytes.end()); |
| 4080 vector<MappedMemoryRegion> all_regions; |
| 4081 |
| 4082 // Parse string into mapping data. |
| 4083 if (!ParseProcMaps(map_string, &all_regions)) { |
| 4084 return false; |
| 4085 } |
| 4086 |
| 4087 scoped_ptr<MinidumpLinuxMappings> maps(new MinidumpLinuxMappings()); |
| 4088 |
| 4089 // Push mapping data into wrapper classes. |
| 4090 for (size_t i = 0; i < all_regions.size(); i++) { |
| 4091 scoped_ptr<MinidumpLinuxMaps> ele(new MinidumpLinuxMaps(minidump_)); |
| 4092 ele->region_ = all_regions[i]; |
| 4093 ele->valid_ = true; |
| 4094 maps->push_back(ele.release()); |
| 4095 } |
| 4096 |
| 4097 // Set instance variables. |
| 4098 maps_ = maps.release(); |
| 4099 maps_count_ = maps_->size(); |
| 4100 valid_ = true; |
| 4101 return true; |
| 4102 } |
| 4103 |
| 4104 void MinidumpLinuxMapsList::Print() { |
| 4105 if (!valid_) { |
| 4106 BPLOG(ERROR) << "MinidumpLinuxMapsList cannot print valid data"; |
| 4107 return; |
| 4108 } |
| 4109 for (size_t i = 0; i < maps_->size(); i++) { |
| 4110 (*maps_)[i]->Print(); |
| 4111 } |
| 4112 } |
3975 | 4113 |
3976 // | 4114 // |
3977 // Minidump | 4115 // Minidump |
3978 // | 4116 // |
3979 | 4117 |
3980 | 4118 |
3981 uint32_t Minidump::max_streams_ = 128; | 4119 uint32_t Minidump::max_streams_ = 128; |
3982 unsigned int Minidump::max_string_length_ = 1024; | 4120 unsigned int Minidump::max_string_length_ = 1024; |
3983 | 4121 |
3984 | 4122 |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4285 MinidumpBreakpadInfo* Minidump::GetBreakpadInfo() { | 4423 MinidumpBreakpadInfo* Minidump::GetBreakpadInfo() { |
4286 MinidumpBreakpadInfo* breakpad_info; | 4424 MinidumpBreakpadInfo* breakpad_info; |
4287 return GetStream(&breakpad_info); | 4425 return GetStream(&breakpad_info); |
4288 } | 4426 } |
4289 | 4427 |
4290 MinidumpMemoryInfoList* Minidump::GetMemoryInfoList() { | 4428 MinidumpMemoryInfoList* Minidump::GetMemoryInfoList() { |
4291 MinidumpMemoryInfoList* memory_info_list; | 4429 MinidumpMemoryInfoList* memory_info_list; |
4292 return GetStream(&memory_info_list); | 4430 return GetStream(&memory_info_list); |
4293 } | 4431 } |
4294 | 4432 |
| 4433 MinidumpLinuxMapsList *Minidump::GetLinuxMapsList() { |
| 4434 MinidumpLinuxMapsList *linux_maps_list; |
| 4435 return GetStream(&linux_maps_list); |
| 4436 } |
| 4437 |
4295 static const char* get_stream_name(uint32_t stream_type) { | 4438 static const char* get_stream_name(uint32_t stream_type) { |
4296 switch (stream_type) { | 4439 switch (stream_type) { |
4297 case MD_UNUSED_STREAM: | 4440 case MD_UNUSED_STREAM: |
4298 return "MD_UNUSED_STREAM"; | 4441 return "MD_UNUSED_STREAM"; |
4299 case MD_RESERVED_STREAM_0: | 4442 case MD_RESERVED_STREAM_0: |
4300 return "MD_RESERVED_STREAM_0"; | 4443 return "MD_RESERVED_STREAM_0"; |
4301 case MD_RESERVED_STREAM_1: | 4444 case MD_RESERVED_STREAM_1: |
4302 return "MD_RESERVED_STREAM_1"; | 4445 return "MD_RESERVED_STREAM_1"; |
4303 case MD_THREAD_LIST_STREAM: | 4446 case MD_THREAD_LIST_STREAM: |
4304 return "MD_THREAD_LIST_STREAM"; | 4447 return "MD_THREAD_LIST_STREAM"; |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4622 return NULL; | 4765 return NULL; |
4623 } | 4766 } |
4624 | 4767 |
4625 *stream = new_stream.release(); | 4768 *stream = new_stream.release(); |
4626 info->stream = *stream; | 4769 info->stream = *stream; |
4627 return *stream; | 4770 return *stream; |
4628 } | 4771 } |
4629 | 4772 |
4630 | 4773 |
4631 } // namespace google_breakpad | 4774 } // namespace google_breakpad |
OLD | NEW |