| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
| 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at |
| 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. |
| 14 |
| 15 #include "snapshot/win/module_snapshot_win.h" |
| 16 |
| 17 #include "base/strings/utf_string_conversions.h" |
| 18 #include "snapshot/win/pe_image_annotations_reader.h" |
| 19 #include "snapshot/win/pe_image_reader.h" |
| 20 #include "util/misc/tri_state.h" |
| 21 #include "util/misc/uuid.h" |
| 22 #include "util/win/module_version.h" |
| 23 |
| 24 namespace crashpad { |
| 25 namespace internal { |
| 26 |
| 27 ModuleSnapshotWin::ModuleSnapshotWin() |
| 28 : ModuleSnapshot(), |
| 29 name_(), |
| 30 pdb_name_(), |
| 31 uuid_(), |
| 32 pe_image_reader_(), |
| 33 process_reader_(nullptr), |
| 34 timestamp_(0), |
| 35 age_(0), |
| 36 initialized_(), |
| 37 vs_fixed_file_info_(), |
| 38 initialized_vs_fixed_file_info_() { |
| 39 } |
| 40 |
| 41 ModuleSnapshotWin::~ModuleSnapshotWin() { |
| 42 } |
| 43 |
| 44 bool ModuleSnapshotWin::Initialize( |
| 45 ProcessReaderWin* process_reader, |
| 46 const ProcessInfo::Module& process_reader_module) { |
| 47 INITIALIZATION_STATE_SET_INITIALIZING(initialized_); |
| 48 |
| 49 process_reader_ = process_reader; |
| 50 name_ = process_reader_module.name; |
| 51 timestamp_ = process_reader_module.timestamp; |
| 52 pe_image_reader_.reset(new PEImageReader()); |
| 53 if (!pe_image_reader_->Initialize(process_reader_, |
| 54 process_reader_module.dll_base, |
| 55 process_reader_module.size, |
| 56 base::UTF16ToUTF8(name_))) { |
| 57 return false; |
| 58 } |
| 59 |
| 60 DWORD age_dword; |
| 61 if (pe_image_reader_->DebugDirectoryInformation( |
| 62 &uuid_, &age_dword, &pdb_name_)) { |
| 63 static_assert(sizeof(DWORD) == sizeof(uint32_t), "unexpected age size"); |
| 64 age_ = age_dword; |
| 65 } else { |
| 66 // If we fully supported all old debugging formats, we would want to extract |
| 67 // and emit a different type of CodeView record here (as old Microsoft tools |
| 68 // would do). As we don't expect to ever encounter a module that wouldn't be |
| 69 // be using .PDB that we actually have symbols for, we simply set a |
| 70 // plausible name here, but this will never correspond to symbols that we |
| 71 // have. |
| 72 pdb_name_ = base::UTF16ToUTF8(name_); |
| 73 } |
| 74 |
| 75 INITIALIZATION_STATE_SET_VALID(initialized_); |
| 76 return true; |
| 77 } |
| 78 |
| 79 void ModuleSnapshotWin::GetCrashpadOptions(CrashpadInfoClientOptions* options) { |
| 80 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 81 if (process_reader_->Is64Bit()) |
| 82 GetCrashpadOptionsInternal<process_types::internal::Traits64>(options); |
| 83 else |
| 84 GetCrashpadOptionsInternal<process_types::internal::Traits32>(options); |
| 85 } |
| 86 |
| 87 std::string ModuleSnapshotWin::Name() const { |
| 88 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 89 return base::UTF16ToUTF8(name_); |
| 90 } |
| 91 |
| 92 uint64_t ModuleSnapshotWin::Address() const { |
| 93 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 94 return pe_image_reader_->Address(); |
| 95 } |
| 96 |
| 97 uint64_t ModuleSnapshotWin::Size() const { |
| 98 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 99 return pe_image_reader_->Size(); |
| 100 } |
| 101 |
| 102 time_t ModuleSnapshotWin::Timestamp() const { |
| 103 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 104 return timestamp_; |
| 105 } |
| 106 |
| 107 void ModuleSnapshotWin::FileVersion(uint16_t* version_0, |
| 108 uint16_t* version_1, |
| 109 uint16_t* version_2, |
| 110 uint16_t* version_3) const { |
| 111 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 112 const VS_FIXEDFILEINFO* ffi = VSFixedFileInfo(); |
| 113 if (ffi) { |
| 114 *version_0 = ffi->dwFileVersionMS >> 16; |
| 115 *version_1 = ffi->dwFileVersionMS & 0xffff; |
| 116 *version_2 = ffi->dwFileVersionLS >> 16; |
| 117 *version_3 = ffi->dwFileVersionLS & 0xffff; |
| 118 } else { |
| 119 *version_0 = 0; |
| 120 *version_1 = 0; |
| 121 *version_2 = 0; |
| 122 *version_3 = 0; |
| 123 } |
| 124 } |
| 125 |
| 126 void ModuleSnapshotWin::SourceVersion(uint16_t* version_0, |
| 127 uint16_t* version_1, |
| 128 uint16_t* version_2, |
| 129 uint16_t* version_3) const { |
| 130 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 131 const VS_FIXEDFILEINFO* ffi = VSFixedFileInfo(); |
| 132 if (ffi) { |
| 133 *version_0 = ffi->dwProductVersionMS >> 16; |
| 134 *version_1 = ffi->dwProductVersionMS & 0xffff; |
| 135 *version_2 = ffi->dwProductVersionLS >> 16; |
| 136 *version_3 = ffi->dwProductVersionLS & 0xffff; |
| 137 } else { |
| 138 *version_0 = 0; |
| 139 *version_1 = 0; |
| 140 *version_2 = 0; |
| 141 *version_3 = 0; |
| 142 } |
| 143 } |
| 144 |
| 145 ModuleSnapshot::ModuleType ModuleSnapshotWin::GetModuleType() const { |
| 146 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 147 const VS_FIXEDFILEINFO* ffi = VSFixedFileInfo(); |
| 148 if (ffi) { |
| 149 switch (ffi->dwFileType) { |
| 150 case VFT_APP: |
| 151 return ModuleSnapshot::kModuleTypeExecutable; |
| 152 case VFT_DLL: |
| 153 return ModuleSnapshot::kModuleTypeSharedLibrary; |
| 154 case VFT_DRV: |
| 155 case VFT_VXD: |
| 156 return ModuleSnapshot::kModuleTypeLoadableModule; |
| 157 } |
| 158 } |
| 159 return ModuleSnapshot::kModuleTypeUnknown; |
| 160 } |
| 161 |
| 162 void ModuleSnapshotWin::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const { |
| 163 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 164 *uuid = uuid_; |
| 165 *age = age_; |
| 166 } |
| 167 |
| 168 std::string ModuleSnapshotWin::DebugFileName() const { |
| 169 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 170 return pdb_name_; |
| 171 } |
| 172 |
| 173 std::vector<std::string> ModuleSnapshotWin::AnnotationsVector() const { |
| 174 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 175 // These correspond to system-logged things on Mac. We don't currently track |
| 176 // any of these on Windows, but could in the future. |
| 177 // See https://crashpad.chromium.org/bug/38. |
| 178 return std::vector<std::string>(); |
| 179 } |
| 180 |
| 181 std::map<std::string, std::string> ModuleSnapshotWin::AnnotationsSimpleMap() |
| 182 const { |
| 183 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 184 PEImageAnnotationsReader annotations_reader( |
| 185 process_reader_, pe_image_reader_.get(), name_); |
| 186 return annotations_reader.SimpleMap(); |
| 187 } |
| 188 |
| 189 template <class Traits> |
| 190 void ModuleSnapshotWin::GetCrashpadOptionsInternal( |
| 191 CrashpadInfoClientOptions* options) { |
| 192 process_types::CrashpadInfo<Traits> crashpad_info; |
| 193 if (!pe_image_reader_->GetCrashpadInfo(&crashpad_info)) { |
| 194 options->crashpad_handler_behavior = TriState::kUnset; |
| 195 options->system_crash_reporter_forwarding = TriState::kUnset; |
| 196 return; |
| 197 } |
| 198 |
| 199 options->crashpad_handler_behavior = |
| 200 CrashpadInfoClientOptions::TriStateFromCrashpadInfo( |
| 201 crashpad_info.crashpad_handler_behavior); |
| 202 |
| 203 options->system_crash_reporter_forwarding = |
| 204 CrashpadInfoClientOptions::TriStateFromCrashpadInfo( |
| 205 crashpad_info.system_crash_reporter_forwarding); |
| 206 } |
| 207 |
| 208 const VS_FIXEDFILEINFO* ModuleSnapshotWin::VSFixedFileInfo() const { |
| 209 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 210 |
| 211 if (initialized_vs_fixed_file_info_.is_uninitialized()) { |
| 212 initialized_vs_fixed_file_info_.set_invalid(); |
| 213 if (GetModuleVersionAndType(base::FilePath(name_), &vs_fixed_file_info_)) { |
| 214 initialized_vs_fixed_file_info_.set_valid(); |
| 215 } |
| 216 } |
| 217 |
| 218 return initialized_vs_fixed_file_info_.is_valid() ? &vs_fixed_file_info_ |
| 219 : nullptr; |
| 220 } |
| 221 |
| 222 } // namespace internal |
| 223 } // namespace crashpad |
| OLD | NEW |