| OLD | NEW |
| 1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 #include "snapshot/win/process_reader_win.h" | 15 #include "snapshot/win/process_reader_win.h" |
| 16 | 16 |
| 17 #include <winternl.h> | 17 #include <winternl.h> |
| 18 | 18 |
| 19 #include "base/memory/scoped_ptr.h" | 19 #include "base/memory/scoped_ptr.h" |
| 20 #include "base/numerics/safe_conversions.h" | 20 #include "base/numerics/safe_conversions.h" |
| 21 #include "base/strings/stringprintf.h" |
| 21 #include "util/win/capture_context.h" | 22 #include "util/win/capture_context.h" |
| 22 #include "util/win/nt_internals.h" | 23 #include "util/win/nt_internals.h" |
| 23 #include "util/win/ntstatus_logging.h" | 24 #include "util/win/ntstatus_logging.h" |
| 24 #include "util/win/process_structs.h" | 25 #include "util/win/process_structs.h" |
| 25 #include "util/win/scoped_handle.h" | 26 #include "util/win/scoped_handle.h" |
| 26 #include "util/win/time.h" | 27 #include "util/win/time.h" |
| 27 | 28 |
| 28 namespace crashpad { | 29 namespace crashpad { |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 suspension_state_ = suspension_state; | 208 suspension_state_ = suspension_state; |
| 208 process_info_.Initialize(process); | 209 process_info_.Initialize(process); |
| 209 | 210 |
| 210 INITIALIZATION_STATE_SET_VALID(initialized_); | 211 INITIALIZATION_STATE_SET_VALID(initialized_); |
| 211 return true; | 212 return true; |
| 212 } | 213 } |
| 213 | 214 |
| 214 bool ProcessReaderWin::ReadMemory(WinVMAddress at, | 215 bool ProcessReaderWin::ReadMemory(WinVMAddress at, |
| 215 WinVMSize num_bytes, | 216 WinVMSize num_bytes, |
| 216 void* into) const { | 217 void* into) const { |
| 218 if (num_bytes == 0) |
| 219 return 0; |
| 220 |
| 217 SIZE_T bytes_read; | 221 SIZE_T bytes_read; |
| 218 if (!ReadProcessMemory(process_, | 222 if (!ReadProcessMemory(process_, |
| 219 reinterpret_cast<void*>(at), | 223 reinterpret_cast<void*>(at), |
| 220 into, | 224 into, |
| 221 base::checked_cast<SIZE_T>(num_bytes), | 225 base::checked_cast<SIZE_T>(num_bytes), |
| 222 &bytes_read) || | 226 &bytes_read) || |
| 223 num_bytes != bytes_read) { | 227 num_bytes != bytes_read) { |
| 224 PLOG(ERROR) << "ReadMemory at 0x" << std::hex << at << std::dec << " of " | 228 PLOG(ERROR) << "ReadMemory at 0x" << std::hex << at << std::dec << " of " |
| 225 << num_bytes << " bytes failed"; | 229 << num_bytes << " bytes failed"; |
| 226 return false; | 230 return false; |
| 227 } | 231 } |
| 228 return true; | 232 return true; |
| 229 } | 233 } |
| 230 | 234 |
| 235 WinVMSize ProcessReaderWin::ReadAvailableMemory(WinVMAddress at, |
| 236 WinVMSize num_bytes, |
| 237 void* into) const { |
| 238 if (num_bytes == 0) |
| 239 return 0; |
| 240 |
| 241 auto ranges = process_info_.GetReadableRanges( |
| 242 CheckedRange<WinVMAddress, WinVMSize>(at, num_bytes)); |
| 243 |
| 244 // We only read up until the first unavailable byte, so we only read from the |
| 245 // first range. If we have no ranges, then no bytes were accessible anywhere |
| 246 // in the range. |
| 247 if (ranges.empty()) { |
| 248 LOG(ERROR) << base::StringPrintf( |
| 249 "range at 0x%llx, size 0x%llx completely inaccessible", at, num_bytes); |
| 250 return 0; |
| 251 } |
| 252 |
| 253 // If the start address was adjusted, we couldn't read even the first |
| 254 // requested byte. |
| 255 if (ranges.front().base() != at) { |
| 256 LOG(ERROR) << base::StringPrintf( |
| 257 "start of range at 0x%llx, size 0x%llx inaccessible", at, num_bytes); |
| 258 return 0; |
| 259 } |
| 260 |
| 261 DCHECK_LE(ranges.front().size(), num_bytes); |
| 262 |
| 263 // If we fail on a normal read, then something went very wrong. |
| 264 if (!ReadMemory(ranges.front().base(), ranges.front().size(), into)) |
| 265 return 0; |
| 266 |
| 267 return ranges.front().size(); |
| 268 } |
| 269 |
| 231 bool ProcessReaderWin::StartTime(timeval* start_time) const { | 270 bool ProcessReaderWin::StartTime(timeval* start_time) const { |
| 232 FILETIME creation, exit, kernel, user; | 271 FILETIME creation, exit, kernel, user; |
| 233 if (!GetProcessTimes(process_, &creation, &exit, &kernel, &user)) { | 272 if (!GetProcessTimes(process_, &creation, &exit, &kernel, &user)) { |
| 234 PLOG(ERROR) << "GetProcessTimes"; | 273 PLOG(ERROR) << "GetProcessTimes"; |
| 235 return false; | 274 return false; |
| 236 } | 275 } |
| 237 *start_time = FiletimeToTimevalEpoch(creation); | 276 *start_time = FiletimeToTimevalEpoch(creation); |
| 238 return true; | 277 return true; |
| 239 } | 278 } |
| 240 | 279 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 thread.stack_region_size = 0; | 401 thread.stack_region_size = 0; |
| 363 } else { | 402 } else { |
| 364 thread.stack_region_size = base - limit; | 403 thread.stack_region_size = base - limit; |
| 365 } | 404 } |
| 366 } | 405 } |
| 367 threads_.push_back(thread); | 406 threads_.push_back(thread); |
| 368 } | 407 } |
| 369 } | 408 } |
| 370 | 409 |
| 371 } // namespace crashpad | 410 } // namespace crashpad |
| OLD | NEW |