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 |