Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: snapshot/win/process_snapshot_win.cc

Issue 1475033005: win: Only capture the loader lock for now (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: . Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « snapshot/win/process_snapshot_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 &extra_memory_); 319 &extra_memory_);
320 AddMemorySnapshotForUNICODE_STRING(process_parameters.ShellInfo, 320 AddMemorySnapshotForUNICODE_STRING(process_parameters.ShellInfo,
321 &extra_memory_); 321 &extra_memory_);
322 AddMemorySnapshotForUNICODE_STRING(process_parameters.RuntimeData, 322 AddMemorySnapshotForUNICODE_STRING(process_parameters.RuntimeData,
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.
330 // not have a .DebugInfo list, but doesn't on more recent OSs (it does on 330 ReadLock<Traits>(peb_data.LoaderLock, &extra_memory_);
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.
333 ReadLocks<Traits>(peb_data.LoaderLock, &extra_memory_);
334 331
335 // Traverse the locks with valid .DebugInfo if a starting point was supplied. 332 // TODO(scottmg): Use debug_critical_section_address to walk the list of
336 if (debug_critical_section_address) 333 // locks (see history of this file for walking code). In some configurations
337 ReadLocks<Traits>(debug_critical_section_address, &extra_memory_); 334 // this can walk many thousands of locks, so we may want to get some
335 // annotation from the client for which locks to grab. Unfortunately, without
336 // walking the list, the !locks command in windbg won't work because it
337 // requires the lock pointed to by ntdll!RtlCriticalSectionList, which we
338 // won't have captured.
338 } 339 }
339 340
340 void ProcessSnapshotWin::AddMemorySnapshot( 341 void ProcessSnapshotWin::AddMemorySnapshot(
341 WinVMAddress address, 342 WinVMAddress address,
342 WinVMSize size, 343 WinVMSize size,
343 PointerVector<internal::MemorySnapshotWin>* into) { 344 PointerVector<internal::MemorySnapshotWin>* into) {
344 if (size == 0) 345 if (size == 0)
345 return; 346 return;
346 347
347 if (!process_reader_.GetProcessInfo().LoggingRangeIsFullyReadable( 348 if (!process_reader_.GetProcessInfo().LoggingRangeIsFullyReadable(
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 static_cast<unsigned int>(bytes_read / sizeof(env_block[0]))); 419 static_cast<unsigned int>(bytes_read / sizeof(env_block[0])));
419 const wchar_t terminator[] = { 0, 0 }; 420 const wchar_t terminator[] = { 0, 0 };
420 size_t at = env_block.find(std::wstring(terminator, arraysize(terminator))); 421 size_t at = env_block.find(std::wstring(terminator, arraysize(terminator)));
421 if (at != std::wstring::npos) 422 if (at != std::wstring::npos)
422 env_block.resize(at + arraysize(terminator)); 423 env_block.resize(at + arraysize(terminator));
423 424
424 return env_block.size() * sizeof(env_block[0]); 425 return env_block.size() * sizeof(env_block[0]);
425 } 426 }
426 427
427 template <class Traits> 428 template <class Traits>
428 void ProcessSnapshotWin::ReadLocks( 429 void ProcessSnapshotWin::ReadLock(
429 WinVMAddress start, 430 WinVMAddress start,
430 PointerVector<internal::MemorySnapshotWin>* into) { 431 PointerVector<internal::MemorySnapshotWin>* into) {
431 // We're walking the RTL_CRITICAL_SECTION_DEBUG ProcessLocksList, but starting 432 // We're walking the RTL_CRITICAL_SECTION_DEBUG ProcessLocksList, but starting
432 // from an actual RTL_CRITICAL_SECTION, so start by getting to the first 433 // from an actual RTL_CRITICAL_SECTION, so start by getting to the first
433 // RTL_CRITICAL_SECTION_DEBUG. 434 // RTL_CRITICAL_SECTION_DEBUG.
434 435
435 process_types::RTL_CRITICAL_SECTION<Traits> critical_section; 436 process_types::RTL_CRITICAL_SECTION<Traits> critical_section;
436 if (!process_reader_.ReadMemory( 437 if (!process_reader_.ReadMemory(
437 start, sizeof(critical_section), &critical_section)) { 438 start, sizeof(critical_section), &critical_section)) {
438 LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION"; 439 LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION";
439 return; 440 return;
440 } 441 }
441 442
443 AddMemorySnapshot(
444 start, sizeof(process_types::RTL_CRITICAL_SECTION<Traits>), into);
445
442 const decltype(critical_section.DebugInfo) kInvalid = 446 const decltype(critical_section.DebugInfo) kInvalid =
443 static_cast<decltype(critical_section.DebugInfo)>(-1); 447 static_cast<decltype(critical_section.DebugInfo)>(-1);
444 if (critical_section.DebugInfo == kInvalid) 448 if (critical_section.DebugInfo == kInvalid)
445 return; 449 return;
446 450
447 const WinVMAddress start_address_backward = critical_section.DebugInfo; 451 AddMemorySnapshot(critical_section.DebugInfo,
448 WinVMAddress current_address = start_address_backward; 452 sizeof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>),
449 WinVMAddress last_good_address; 453 into);
450
451 // 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)
453 // before following Flink to capture memory.
454 do {
455 last_good_address = current_address;
456 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList.
457 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug;
458 if (!process_reader_.ReadMemory(current_address,
459 sizeof(critical_section_debug),
460 &critical_section_debug)) {
461 LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION_DEBUG";
462 return;
463 }
464
465 if (critical_section_debug.ProcessLocksList.Blink == 0) {
466 // At the head of the list.
467 break;
468 }
469
470 // Move to the previous RTL_CRITICAL_SECTION_DEBUG by walking
471 // ProcessLocksList.Blink.
472 current_address =
473 critical_section_debug.ProcessLocksList.Blink -
474 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>,
475 ProcessLocksList);
476 } while (current_address != start_address_backward &&
477 current_address != kInvalid);
478
479 if (current_address == kInvalid) {
480 // Unexpectedly encountered a bad record, so step back one.
481 current_address = last_good_address;
482 }
483
484 const WinVMAddress start_address_forward = current_address;
485
486 // current_address is now the head of the list, walk Flink to add the whole
487 // list.
488 do {
489 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList.
490 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug;
491 if (!process_reader_.ReadMemory(current_address,
492 sizeof(critical_section_debug),
493 &critical_section_debug)) {
494 LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION_DEBUG";
495 return;
496 }
497
498 // Add both RTL_CRITICAL_SECTION_DEBUG and RTL_CRITICAL_SECTION to the extra
499 // memory to be saved.
500 AddMemorySnapshot(current_address,
501 sizeof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>),
502 into);
503 AddMemorySnapshot(critical_section_debug.CriticalSection,
504 sizeof(process_types::RTL_CRITICAL_SECTION<Traits>),
505 into);
506
507 if (critical_section_debug.ProcessLocksList.Flink == 0)
508 break;
509
510 // Move to the next RTL_CRITICAL_SECTION_DEBUG by walking
511 // ProcessLocksList.Flink.
512 current_address =
513 critical_section_debug.ProcessLocksList.Flink -
514 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>,
515 ProcessLocksList);
516 } while (current_address != start_address_forward &&
517 current_address != kInvalid);
518 } 454 }
519 455
520 } // namespace crashpad 456 } // namespace crashpad
OLDNEW
« no previous file with comments | « snapshot/win/process_snapshot_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698