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 430 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; | |
453 int walk_count = 0; | |
454 | |
455 // Typically, this seems to be a circular list, but it's not clear that it | 451 // Typically, this seems to be a circular list, but it's not clear that it |
456 // always is, so follow Blink fields back to the head (or where we started) | 452 // always is, so follow Blink fields back to the head (or where we started) |
457 // before following Flink to capture memory. | 453 // before following Flink to capture memory. |
458 do { | 454 do { |
459 last_good_address = current_address; | 455 last_good_address = current_address; |
460 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList. | 456 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList. |
461 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug; | 457 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug; |
462 if (!process_reader_.ReadMemory(current_address, | 458 if (!process_reader_.ReadMemory(current_address, |
463 sizeof(critical_section_debug), | 459 sizeof(critical_section_debug), |
464 &critical_section_debug)) { | 460 &critical_section_debug)) { |
465 LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION_DEBUG"; | 461 LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION_DEBUG"; |
466 return; | 462 return; |
467 } | 463 } |
468 | 464 |
469 if (critical_section_debug.ProcessLocksList.Blink == 0) { | 465 if (critical_section_debug.ProcessLocksList.Blink == 0) { |
470 // At the head of the list. | 466 // At the head of the list. |
471 break; | 467 break; |
472 } | 468 } |
473 | 469 |
474 // Move to the previous RTL_CRITICAL_SECTION_DEBUG by walking | 470 // Move to the previous RTL_CRITICAL_SECTION_DEBUG by walking |
475 // ProcessLocksList.Blink. | 471 // ProcessLocksList.Blink. |
476 current_address = | 472 current_address = |
477 critical_section_debug.ProcessLocksList.Blink - | 473 critical_section_debug.ProcessLocksList.Blink - |
478 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>, | 474 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>, |
479 ProcessLocksList); | 475 ProcessLocksList); |
480 walk_count++; | |
481 if (walk_count == kMaxWalkLength) | |
482 break; | |
483 } while (current_address != start_address_backward && | 476 } while (current_address != start_address_backward && |
484 current_address != kInvalid); | 477 current_address != kInvalid); |
485 | 478 |
486 if (current_address == kInvalid) { | 479 if (current_address == kInvalid) { |
487 // Unexpectedly encountered a bad record, so step back one. | 480 // Unexpectedly encountered a bad record, so step back one. |
488 current_address = last_good_address; | 481 current_address = last_good_address; |
489 } | 482 } |
490 | 483 |
491 walk_count = 0; | |
492 | |
493 const WinVMAddress start_address_forward = current_address; | 484 const WinVMAddress start_address_forward = current_address; |
494 | 485 |
495 // current_address is now the head of the list, walk Flink to add the whole | 486 // current_address is now the head of the list, walk Flink to add the whole |
496 // list. | 487 // list. |
497 do { | 488 do { |
498 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList. | 489 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList. |
499 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug; | 490 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug; |
500 if (!process_reader_.ReadMemory(current_address, | 491 if (!process_reader_.ReadMemory(current_address, |
501 sizeof(critical_section_debug), | 492 sizeof(critical_section_debug), |
502 &critical_section_debug)) { | 493 &critical_section_debug)) { |
(...skipping 12 matching lines...) Expand all Loading... |
515 | 506 |
516 if (critical_section_debug.ProcessLocksList.Flink == 0) | 507 if (critical_section_debug.ProcessLocksList.Flink == 0) |
517 break; | 508 break; |
518 | 509 |
519 // Move to the next RTL_CRITICAL_SECTION_DEBUG by walking | 510 // Move to the next RTL_CRITICAL_SECTION_DEBUG by walking |
520 // ProcessLocksList.Flink. | 511 // ProcessLocksList.Flink. |
521 current_address = | 512 current_address = |
522 critical_section_debug.ProcessLocksList.Flink - | 513 critical_section_debug.ProcessLocksList.Flink - |
523 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>, | 514 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>, |
524 ProcessLocksList); | 515 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; | |
531 } while (current_address != start_address_forward && | 516 } while (current_address != start_address_forward && |
532 current_address != kInvalid); | 517 current_address != kInvalid); |
533 } | 518 } |
534 | 519 |
535 } // namespace crashpad | 520 } // namespace crashpad |
OLD | NEW |