mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-20 02:23:47 +00:00
This makes the basics of !peb work in windbg, however, pointed-to things are not yet retrieved. For full functionality, a variety of pointers in the PEB also needs to be walked and captured. e.g. Previously: 0:000> .ecxr eax=00000007 ebx=7e383000 ecx=c3f9a943 edx=00000000 esi=006d62d0 edi=003c9280 eip=00384828 esp=005bf634 ebp=005bf638 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246 crashy_program!crashpad::`anonymous namespace'::SomeCrashyFunction+0x28: 00384828 c7002a000000 mov dword ptr [eax],2Ah ds:002b:00000007=???????? 0:000> !peb PEB at 7e383000 error 1 InitTypeRead( nt!_PEB at 7e383000)... Now: 0:000> .ecxr eax=00000007 ebx=7f958000 ecx=02102f4d edx=00000000 esi=00e162d0 edi=01389280 eip=01344828 esp=00c2fb64 ebp=00c2fb68 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246 crashy_program!crashpad::`anonymous namespace'::SomeCrashyFunction+0x28: 01344828 c7002a000000 mov dword ptr [eax],2Ah ds:002b:00000007=???????? 0:000> !peb PEB at 7f958000 InheritedAddressSpace: No ReadImageFileExecOptions: No BeingDebugged: No ImageBaseAddress: 01340000 Ldr 77ec8b40 *** unable to read Ldr table at 77ec8b40 SubSystemData: 00000000 ProcessHeap: 00e10000 ProcessParameters: 00e114e0 CurrentDirectory: '< Name not readable >' WindowTitle: '< Name not readable >' ImageFile: '< Name not readable >' CommandLine: '< Name not readable >' DllPath: '< Name not readable >' Environment: 00000000 Unable to read Environment string. R=mark@chromium.org BUG=crashpad:46 Review URL: https://codereview.chromium.org/1364053002 .
218 lines
6.7 KiB
C++
218 lines
6.7 KiB
C++
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "snapshot/win/process_snapshot_win.h"
|
|
|
|
#include "base/logging.h"
|
|
#include "snapshot/win/module_snapshot_win.h"
|
|
#include "util/win/registration_protocol_win.h"
|
|
#include "util/win/time.h"
|
|
|
|
namespace crashpad {
|
|
|
|
ProcessSnapshotWin::ProcessSnapshotWin()
|
|
: ProcessSnapshot(),
|
|
system_(),
|
|
threads_(),
|
|
modules_(),
|
|
exception_(),
|
|
process_reader_(),
|
|
report_id_(),
|
|
client_id_(),
|
|
annotations_simple_map_(),
|
|
snapshot_time_(),
|
|
initialized_() {
|
|
}
|
|
|
|
ProcessSnapshotWin::~ProcessSnapshotWin() {
|
|
}
|
|
|
|
bool ProcessSnapshotWin::Initialize(HANDLE process,
|
|
ProcessSuspensionState suspension_state) {
|
|
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
|
|
|
|
GetTimeOfDay(&snapshot_time_);
|
|
|
|
if (!process_reader_.Initialize(process, suspension_state))
|
|
return false;
|
|
|
|
system_.Initialize(&process_reader_);
|
|
WinVMAddress peb_address;
|
|
WinVMSize peb_size;
|
|
process_reader_.GetProcessInfo().Peb(&peb_address, &peb_size);
|
|
peb_.Initialize(&process_reader_, peb_address, peb_size);
|
|
|
|
InitializeThreads();
|
|
InitializeModules();
|
|
|
|
INITIALIZATION_STATE_SET_VALID(initialized_);
|
|
return true;
|
|
}
|
|
|
|
bool ProcessSnapshotWin::InitializeException(
|
|
WinVMAddress exception_information_address) {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
DCHECK(!exception_);
|
|
|
|
ExceptionInformation exception_information;
|
|
if (!process_reader_.ReadMemory(exception_information_address,
|
|
sizeof(exception_information),
|
|
&exception_information)) {
|
|
LOG(WARNING) << "ReadMemory ExceptionInformation failed";
|
|
return false;
|
|
}
|
|
|
|
exception_.reset(new internal::ExceptionSnapshotWin());
|
|
if (!exception_->Initialize(&process_reader_,
|
|
exception_information.thread_id,
|
|
exception_information.exception_pointers)) {
|
|
exception_.reset();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void ProcessSnapshotWin::GetCrashpadOptions(
|
|
CrashpadInfoClientOptions* options) {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
|
|
CrashpadInfoClientOptions local_options;
|
|
|
|
for (internal::ModuleSnapshotWin* module : modules_) {
|
|
CrashpadInfoClientOptions module_options;
|
|
module->GetCrashpadOptions(&module_options);
|
|
|
|
if (local_options.crashpad_handler_behavior == TriState::kUnset) {
|
|
local_options.crashpad_handler_behavior =
|
|
module_options.crashpad_handler_behavior;
|
|
}
|
|
if (local_options.system_crash_reporter_forwarding == TriState::kUnset) {
|
|
local_options.system_crash_reporter_forwarding =
|
|
module_options.system_crash_reporter_forwarding;
|
|
}
|
|
|
|
// If non-default values have been found for all options, the loop can end
|
|
// early.
|
|
if (local_options.crashpad_handler_behavior != TriState::kUnset &&
|
|
local_options.system_crash_reporter_forwarding != TriState::kUnset) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
*options = local_options;
|
|
}
|
|
|
|
pid_t ProcessSnapshotWin::ProcessID() const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
return process_reader_.GetProcessInfo().ProcessID();
|
|
}
|
|
|
|
pid_t ProcessSnapshotWin::ParentProcessID() const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
return process_reader_.GetProcessInfo().ParentProcessID();
|
|
}
|
|
|
|
void ProcessSnapshotWin::SnapshotTime(timeval* snapshot_time) const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
*snapshot_time = snapshot_time_;
|
|
}
|
|
|
|
void ProcessSnapshotWin::ProcessStartTime(timeval* start_time) const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
process_reader_.StartTime(start_time);
|
|
}
|
|
|
|
void ProcessSnapshotWin::ProcessCPUTimes(timeval* user_time,
|
|
timeval* system_time) const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
process_reader_.CPUTimes(user_time, system_time);
|
|
}
|
|
|
|
void ProcessSnapshotWin::ReportID(UUID* report_id) const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
*report_id = report_id_;
|
|
}
|
|
|
|
void ProcessSnapshotWin::ClientID(UUID* client_id) const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
*client_id = client_id_;
|
|
}
|
|
|
|
const std::map<std::string, std::string>&
|
|
ProcessSnapshotWin::AnnotationsSimpleMap() const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
return annotations_simple_map_;
|
|
}
|
|
|
|
const SystemSnapshot* ProcessSnapshotWin::System() const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
return &system_;
|
|
}
|
|
|
|
std::vector<const ThreadSnapshot*> ProcessSnapshotWin::Threads() const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
std::vector<const ThreadSnapshot*> threads;
|
|
for (internal::ThreadSnapshotWin* thread : threads_) {
|
|
threads.push_back(thread);
|
|
}
|
|
return threads;
|
|
}
|
|
|
|
std::vector<const ModuleSnapshot*> ProcessSnapshotWin::Modules() const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
std::vector<const ModuleSnapshot*> modules;
|
|
for (internal::ModuleSnapshotWin* module : modules_) {
|
|
modules.push_back(module);
|
|
}
|
|
return modules;
|
|
}
|
|
|
|
const ExceptionSnapshot* ProcessSnapshotWin::Exception() const {
|
|
return exception_.get();
|
|
}
|
|
|
|
std::vector<const MemorySnapshot*> ProcessSnapshotWin::ExtraMemory() const {
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
std::vector<const MemorySnapshot*> extra_memory;
|
|
extra_memory.push_back(&peb_);
|
|
return extra_memory;
|
|
}
|
|
|
|
void ProcessSnapshotWin::InitializeThreads() {
|
|
const std::vector<ProcessReaderWin::Thread>& process_reader_threads =
|
|
process_reader_.Threads();
|
|
for (const ProcessReaderWin::Thread& process_reader_thread :
|
|
process_reader_threads) {
|
|
auto thread = make_scoped_ptr(new internal::ThreadSnapshotWin());
|
|
if (thread->Initialize(&process_reader_, process_reader_thread)) {
|
|
threads_.push_back(thread.release());
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProcessSnapshotWin::InitializeModules() {
|
|
const std::vector<ProcessInfo::Module>& process_reader_modules =
|
|
process_reader_.Modules();
|
|
for (const ProcessInfo::Module& process_reader_module :
|
|
process_reader_modules) {
|
|
auto module = make_scoped_ptr(new internal::ModuleSnapshotWin());
|
|
if (module->Initialize(&process_reader_, process_reader_module)) {
|
|
modules_.push_back(module.release());
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace crashpad
|