Chromium Code Reviews| 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, |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 &extra_memory_); | 323 &extra_memory_); |
| 324 AddMemorySnapshot( | 324 AddMemorySnapshot( |
| 325 process_parameters.Environment, | 325 process_parameters.Environment, |
| 326 DetermineSizeOfEnvironmentBlock(process_parameters.Environment), | 326 DetermineSizeOfEnvironmentBlock(process_parameters.Environment), |
| 327 &extra_memory_); | 327 &extra_memory_); |
| 328 | 328 |
| 329 // Walk the loader lock which is directly referenced by the PEB. It may or may | 329 // Walk the loader lock which is directly referenced by the PEB. It may or may |
| 330 // not have a .DebugInfo list, but doesn't on more recent OSs (it does on | 330 // not have a .DebugInfo list, but doesn't on more recent OSs (it does on |
| 331 // Vista). If it does, then we may walk the lock list more than once, but | 331 // Vista). If it does, then we may walk the lock list more than once, but |
| 332 // AddMemorySnapshot() will take care of deduplicating the added regions. | 332 // AddMemorySnapshot() will take care of deduplicating the added regions. |
| 333 ReadLocks<Traits>(peb_data.LoaderLock, &extra_memory_); | 333 ReadLocks<Traits>(peb_data.LoaderLock, &extra_memory_); |
|
Mark Mentovai
2015/11/30 18:32:06
If we really only care about the loader lock, mayb
| |
| 334 | 334 |
| 335 // Traverse the locks with valid .DebugInfo if a starting point was supplied. | 335 // Traverse the locks with valid .DebugInfo if a starting point was supplied. |
| 336 if (debug_critical_section_address) | 336 if (debug_critical_section_address) |
| 337 ReadLocks<Traits>(debug_critical_section_address, &extra_memory_); | 337 ReadLocks<Traits>(debug_critical_section_address, &extra_memory_); |
| 338 } | 338 } |
| 339 | 339 |
| 340 void ProcessSnapshotWin::AddMemorySnapshot( | 340 void ProcessSnapshotWin::AddMemorySnapshot( |
| 341 WinVMAddress address, | 341 WinVMAddress address, |
| 342 WinVMSize size, | 342 WinVMSize size, |
| 343 PointerVector<internal::MemorySnapshotWin>* into) { | 343 PointerVector<internal::MemorySnapshotWin>* into) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 441 | 441 |
| 442 const decltype(critical_section.DebugInfo) kInvalid = | 442 const decltype(critical_section.DebugInfo) kInvalid = |
| 443 static_cast<decltype(critical_section.DebugInfo)>(-1); | 443 static_cast<decltype(critical_section.DebugInfo)>(-1); |
| 444 if (critical_section.DebugInfo == kInvalid) | 444 if (critical_section.DebugInfo == kInvalid) |
| 445 return; | 445 return; |
| 446 | 446 |
| 447 const WinVMAddress start_address_backward = critical_section.DebugInfo; | 447 const WinVMAddress start_address_backward = critical_section.DebugInfo; |
| 448 WinVMAddress current_address = start_address_backward; | 448 WinVMAddress current_address = start_address_backward; |
| 449 WinVMAddress last_good_address; | 449 WinVMAddress last_good_address; |
| 450 | 450 |
| 451 // Cap the list of locks we capture arbitrarily so we don't walk forever. | |
| 452 const int kMaxWalkLength = 100; | |
|
Mark Mentovai
2015/11/30 18:32:06
…and maybe we should just grab the loader lock her
| |
| 453 int walk_count = 0; | |
| 454 | |
| 451 // Typically, this seems to be a circular list, but it's not clear that it | 455 // Typically, this seems to be a circular list, but it's not clear that it |
| 452 // always is, so follow Blink fields back to the head (or where we started) | 456 // always is, so follow Blink fields back to the head (or where we started) |
| 453 // before following Flink to capture memory. | 457 // before following Flink to capture memory. |
| 454 do { | 458 do { |
| 455 last_good_address = current_address; | 459 last_good_address = current_address; |
| 456 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList. | 460 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList. |
| 457 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug; | 461 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug; |
| 458 if (!process_reader_.ReadMemory(current_address, | 462 if (!process_reader_.ReadMemory(current_address, |
| 459 sizeof(critical_section_debug), | 463 sizeof(critical_section_debug), |
| 460 &critical_section_debug)) { | 464 &critical_section_debug)) { |
| 461 LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION_DEBUG"; | 465 LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION_DEBUG"; |
| 462 return; | 466 return; |
| 463 } | 467 } |
| 464 | 468 |
| 465 if (critical_section_debug.ProcessLocksList.Blink == 0) { | 469 if (critical_section_debug.ProcessLocksList.Blink == 0) { |
| 466 // At the head of the list. | 470 // At the head of the list. |
| 467 break; | 471 break; |
| 468 } | 472 } |
| 469 | 473 |
| 470 // Move to the previous RTL_CRITICAL_SECTION_DEBUG by walking | 474 // Move to the previous RTL_CRITICAL_SECTION_DEBUG by walking |
| 471 // ProcessLocksList.Blink. | 475 // ProcessLocksList.Blink. |
| 472 current_address = | 476 current_address = |
| 473 critical_section_debug.ProcessLocksList.Blink - | 477 critical_section_debug.ProcessLocksList.Blink - |
| 474 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>, | 478 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>, |
| 475 ProcessLocksList); | 479 ProcessLocksList); |
| 480 walk_count++; | |
| 481 if (walk_count == kMaxWalkLength) | |
| 482 break; | |
| 476 } while (current_address != start_address_backward && | 483 } while (current_address != start_address_backward && |
| 477 current_address != kInvalid); | 484 current_address != kInvalid); |
| 478 | 485 |
| 479 if (current_address == kInvalid) { | 486 if (current_address == kInvalid) { |
| 480 // Unexpectedly encountered a bad record, so step back one. | 487 // Unexpectedly encountered a bad record, so step back one. |
| 481 current_address = last_good_address; | 488 current_address = last_good_address; |
| 482 } | 489 } |
| 483 | 490 |
| 491 walk_count = 0; | |
| 492 | |
| 484 const WinVMAddress start_address_forward = current_address; | 493 const WinVMAddress start_address_forward = current_address; |
| 485 | 494 |
| 486 // current_address is now the head of the list, walk Flink to add the whole | 495 // current_address is now the head of the list, walk Flink to add the whole |
| 487 // list. | 496 // list. |
| 488 do { | 497 do { |
| 489 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList. | 498 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList. |
| 490 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug; | 499 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug; |
| 491 if (!process_reader_.ReadMemory(current_address, | 500 if (!process_reader_.ReadMemory(current_address, |
| 492 sizeof(critical_section_debug), | 501 sizeof(critical_section_debug), |
| 493 &critical_section_debug)) { | 502 &critical_section_debug)) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 506 | 515 |
| 507 if (critical_section_debug.ProcessLocksList.Flink == 0) | 516 if (critical_section_debug.ProcessLocksList.Flink == 0) |
| 508 break; | 517 break; |
| 509 | 518 |
| 510 // Move to the next RTL_CRITICAL_SECTION_DEBUG by walking | 519 // Move to the next RTL_CRITICAL_SECTION_DEBUG by walking |
| 511 // ProcessLocksList.Flink. | 520 // ProcessLocksList.Flink. |
| 512 current_address = | 521 current_address = |
| 513 critical_section_debug.ProcessLocksList.Flink - | 522 critical_section_debug.ProcessLocksList.Flink - |
| 514 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>, | 523 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>, |
| 515 ProcessLocksList); | 524 ProcessLocksList); |
| 525 walk_count++; | |
| 526 // Walk twice as far on the forward walk, so that if we started at an | |
| 527 // important one (for example the Loader Lock), we get it, and ones that | |
| 528 // were presumably allocated temporally near it. | |
| 529 if (walk_count == kMaxWalkLength * 2) | |
| 530 break; | |
| 516 } while (current_address != start_address_forward && | 531 } while (current_address != start_address_forward && |
| 517 current_address != kInvalid); | 532 current_address != kInvalid); |
| 518 } | 533 } |
| 519 | 534 |
| 520 } // namespace crashpad | 535 } // namespace crashpad |
| OLD | NEW |