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

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

Issue 1392093003: win: Capture some CRITICAL_SECTION debugging data (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: . Created 5 years, 2 months 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
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 23 matching lines...) Expand all
34 report_id_(), 34 report_id_(),
35 client_id_(), 35 client_id_(),
36 annotations_simple_map_(), 36 annotations_simple_map_(),
37 snapshot_time_(), 37 snapshot_time_(),
38 initialized_() { 38 initialized_() {
39 } 39 }
40 40
41 ProcessSnapshotWin::~ProcessSnapshotWin() { 41 ProcessSnapshotWin::~ProcessSnapshotWin() {
42 } 42 }
43 43
44 bool ProcessSnapshotWin::Initialize(HANDLE process, 44 bool ProcessSnapshotWin::Initialize(
45 ProcessSuspensionState suspension_state) { 45 HANDLE process,
46 ProcessSuspensionState suspension_state,
47 WinVMAddress debug_critical_section_address) {
46 INITIALIZATION_STATE_SET_INITIALIZING(initialized_); 48 INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
47 49
48 GetTimeOfDay(&snapshot_time_); 50 GetTimeOfDay(&snapshot_time_);
49 51
50 if (!process_reader_.Initialize(process, suspension_state)) 52 if (!process_reader_.Initialize(process, suspension_state))
51 return false; 53 return false;
52 54
53 system_.Initialize(&process_reader_); 55 system_.Initialize(&process_reader_);
54 56
55 if (process_reader_.Is64Bit()) 57 if (process_reader_.Is64Bit()) {
56 InitializePebData<process_types::internal::Traits64>(); 58 InitializePebData<process_types::internal::Traits64>(
57 else 59 debug_critical_section_address);
58 InitializePebData<process_types::internal::Traits32>(); 60 } else {
61 InitializePebData<process_types::internal::Traits32>(
62 debug_critical_section_address);
63 }
59 64
60 InitializeThreads(); 65 InitializeThreads();
61 InitializeModules(); 66 InitializeModules();
62 67
63 INITIALIZATION_STATE_SET_VALID(initialized_); 68 INITIALIZATION_STATE_SET_VALID(initialized_);
64 return true; 69 return true;
65 } 70 }
66 71
67 bool ProcessSnapshotWin::InitializeException( 72 bool ProcessSnapshotWin::InitializeException(
68 WinVMAddress exception_information_address) { 73 WinVMAddress exception_information_address) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 return modules; 188 return modules;
184 } 189 }
185 190
186 const ExceptionSnapshot* ProcessSnapshotWin::Exception() const { 191 const ExceptionSnapshot* ProcessSnapshotWin::Exception() const {
187 return exception_.get(); 192 return exception_.get();
188 } 193 }
189 194
190 std::vector<const MemorySnapshot*> ProcessSnapshotWin::ExtraMemory() const { 195 std::vector<const MemorySnapshot*> ProcessSnapshotWin::ExtraMemory() const {
191 INITIALIZATION_STATE_DCHECK_VALID(initialized_); 196 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
192 std::vector<const MemorySnapshot*> extra_memory; 197 std::vector<const MemorySnapshot*> extra_memory;
193 for (const auto& peb_memory : peb_memory_) 198 for (const auto& em : extra_memory_)
194 extra_memory.push_back(peb_memory); 199 extra_memory.push_back(em);
195 return extra_memory; 200 return extra_memory;
196 } 201 }
197 202
198 void ProcessSnapshotWin::InitializeThreads() { 203 void ProcessSnapshotWin::InitializeThreads() {
199 const std::vector<ProcessReaderWin::Thread>& process_reader_threads = 204 const std::vector<ProcessReaderWin::Thread>& process_reader_threads =
200 process_reader_.Threads(); 205 process_reader_.Threads();
201 for (const ProcessReaderWin::Thread& process_reader_thread : 206 for (const ProcessReaderWin::Thread& process_reader_thread :
202 process_reader_threads) { 207 process_reader_threads) {
203 auto thread = make_scoped_ptr(new internal::ThreadSnapshotWin()); 208 auto thread = make_scoped_ptr(new internal::ThreadSnapshotWin());
204 if (thread->Initialize(&process_reader_, process_reader_thread)) { 209 if (thread->Initialize(&process_reader_, process_reader_thread)) {
205 threads_.push_back(thread.release()); 210 threads_.push_back(thread.release());
206 } 211 }
207 } 212 }
208 } 213 }
209 214
210 void ProcessSnapshotWin::InitializeModules() { 215 void ProcessSnapshotWin::InitializeModules() {
211 const std::vector<ProcessInfo::Module>& process_reader_modules = 216 const std::vector<ProcessInfo::Module>& process_reader_modules =
212 process_reader_.Modules(); 217 process_reader_.Modules();
213 for (const ProcessInfo::Module& process_reader_module : 218 for (const ProcessInfo::Module& process_reader_module :
214 process_reader_modules) { 219 process_reader_modules) {
215 auto module = make_scoped_ptr(new internal::ModuleSnapshotWin()); 220 auto module = make_scoped_ptr(new internal::ModuleSnapshotWin());
216 if (module->Initialize(&process_reader_, process_reader_module)) { 221 if (module->Initialize(&process_reader_, process_reader_module)) {
217 modules_.push_back(module.release()); 222 modules_.push_back(module.release());
218 } 223 }
219 } 224 }
220 } 225 }
221 226
222 template <class Traits> 227 template <class Traits>
223 void ProcessSnapshotWin::InitializePebData() { 228 void ProcessSnapshotWin::InitializePebData(
229 WinVMAddress debug_critical_section_address) {
224 WinVMAddress peb_address; 230 WinVMAddress peb_address;
225 WinVMSize peb_size; 231 WinVMSize peb_size;
226 process_reader_.GetProcessInfo().Peb(&peb_address, &peb_size); 232 process_reader_.GetProcessInfo().Peb(&peb_address, &peb_size);
227 AddMemorySnapshot(peb_address, peb_size, &peb_memory_); 233 AddMemorySnapshot(peb_address, peb_size, &extra_memory_);
228 234
229 process_types::PEB<Traits> peb_data; 235 process_types::PEB<Traits> peb_data;
230 if (!process_reader_.ReadMemory(peb_address, peb_size, &peb_data)) { 236 if (!process_reader_.ReadMemory(peb_address, peb_size, &peb_data)) {
231 LOG(ERROR) << "ReadMemory PEB"; 237 LOG(ERROR) << "ReadMemory PEB";
232 return; 238 return;
233 } 239 }
234 240
235 process_types::PEB_LDR_DATA<Traits> peb_ldr_data; 241 process_types::PEB_LDR_DATA<Traits> peb_ldr_data;
236 AddMemorySnapshot(peb_data.Ldr, sizeof(peb_ldr_data), &peb_memory_); 242 AddMemorySnapshot(peb_data.Ldr, sizeof(peb_ldr_data), &extra_memory_);
237 if (!process_reader_.ReadMemory( 243 if (!process_reader_.ReadMemory(
238 peb_data.Ldr, sizeof(peb_ldr_data), &peb_ldr_data)) { 244 peb_data.Ldr, sizeof(peb_ldr_data), &peb_ldr_data)) {
239 LOG(ERROR) << "ReadMemory PEB_LDR_DATA"; 245 LOG(ERROR) << "ReadMemory PEB_LDR_DATA";
240 } else { 246 } else {
241 // Walk the LDR structure to retrieve its pointed-to data. 247 // Walk the LDR structure to retrieve its pointed-to data.
242 AddMemorySnapshotForLdrLIST_ENTRY( 248 AddMemorySnapshotForLdrLIST_ENTRY(
243 peb_ldr_data.InLoadOrderModuleList, 249 peb_ldr_data.InLoadOrderModuleList,
244 offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>, InLoadOrderLinks), 250 offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>, InLoadOrderLinks),
245 &peb_memory_); 251 &extra_memory_);
246 AddMemorySnapshotForLdrLIST_ENTRY( 252 AddMemorySnapshotForLdrLIST_ENTRY(
247 peb_ldr_data.InMemoryOrderModuleList, 253 peb_ldr_data.InMemoryOrderModuleList,
248 offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>, 254 offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>,
249 InMemoryOrderLinks), 255 InMemoryOrderLinks),
250 &peb_memory_); 256 &extra_memory_);
251 AddMemorySnapshotForLdrLIST_ENTRY( 257 AddMemorySnapshotForLdrLIST_ENTRY(
252 peb_ldr_data.InInitializationOrderModuleList, 258 peb_ldr_data.InInitializationOrderModuleList,
253 offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>, 259 offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>,
254 InInitializationOrderLinks), 260 InInitializationOrderLinks),
255 &peb_memory_); 261 &extra_memory_);
256 } 262 }
257 263
258 process_types::RTL_USER_PROCESS_PARAMETERS<Traits> process_parameters; 264 process_types::RTL_USER_PROCESS_PARAMETERS<Traits> process_parameters;
259 if (!process_reader_.ReadMemory(peb_data.ProcessParameters, 265 if (!process_reader_.ReadMemory(peb_data.ProcessParameters,
260 sizeof(process_parameters), 266 sizeof(process_parameters),
261 &process_parameters)) { 267 &process_parameters)) {
262 LOG(ERROR) << "ReadMemory RTL_USER_PROCESS_PARAMETERS"; 268 LOG(ERROR) << "ReadMemory RTL_USER_PROCESS_PARAMETERS";
263 return; 269 return;
264 } 270 }
265 AddMemorySnapshot( 271 AddMemorySnapshot(
266 peb_data.ProcessParameters, sizeof(process_parameters), &peb_memory_); 272 peb_data.ProcessParameters, sizeof(process_parameters), &extra_memory_);
267 273
268 AddMemorySnapshotForUNICODE_STRING( 274 AddMemorySnapshotForUNICODE_STRING(
269 process_parameters.CurrentDirectory.DosPath, &peb_memory_); 275 process_parameters.CurrentDirectory.DosPath, &extra_memory_);
270 AddMemorySnapshotForUNICODE_STRING(process_parameters.DllPath, &peb_memory_); 276 AddMemorySnapshotForUNICODE_STRING(process_parameters.DllPath,
277 &extra_memory_);
271 AddMemorySnapshotForUNICODE_STRING(process_parameters.ImagePathName, 278 AddMemorySnapshotForUNICODE_STRING(process_parameters.ImagePathName,
272 &peb_memory_); 279 &extra_memory_);
273 AddMemorySnapshotForUNICODE_STRING(process_parameters.CommandLine, 280 AddMemorySnapshotForUNICODE_STRING(process_parameters.CommandLine,
274 &peb_memory_); 281 &extra_memory_);
275 AddMemorySnapshotForUNICODE_STRING(process_parameters.WindowTitle, 282 AddMemorySnapshotForUNICODE_STRING(process_parameters.WindowTitle,
276 &peb_memory_); 283 &extra_memory_);
277 AddMemorySnapshotForUNICODE_STRING(process_parameters.DesktopInfo, 284 AddMemorySnapshotForUNICODE_STRING(process_parameters.DesktopInfo,
278 &peb_memory_); 285 &extra_memory_);
279 AddMemorySnapshotForUNICODE_STRING(process_parameters.ShellInfo, 286 AddMemorySnapshotForUNICODE_STRING(process_parameters.ShellInfo,
280 &peb_memory_); 287 &extra_memory_);
281 AddMemorySnapshotForUNICODE_STRING(process_parameters.RuntimeData, 288 AddMemorySnapshotForUNICODE_STRING(process_parameters.RuntimeData,
282 &peb_memory_); 289 &extra_memory_);
283 AddMemorySnapshot( 290 AddMemorySnapshot(
284 process_parameters.Environment, 291 process_parameters.Environment,
285 DetermineSizeOfEnvironmentBlock(process_parameters.Environment), 292 DetermineSizeOfEnvironmentBlock(process_parameters.Environment),
286 &peb_memory_); 293 &extra_memory_);
294
295 // Walk the loader lock which is directly referenced by the PEB. It may or may
296 // not have a .DebugInfo list, but typically doesn't. If it does, then we may
297 // walk the lock list more than once, but AddMemorySnapshot() will take care
298 // of deduplicating the added regions.
299 ReadLocks<Traits>(peb_data.LoaderLock, &extra_memory_);
300
301 // Traverse the locks with valid .DebugInfo if a starting point was supplied.
302 if (debug_critical_section_address)
303 ReadLocks<Traits>(debug_critical_section_address, &extra_memory_);
287 } 304 }
288 305
289 void ProcessSnapshotWin::AddMemorySnapshot( 306 void ProcessSnapshotWin::AddMemorySnapshot(
290 WinVMAddress address, 307 WinVMAddress address,
291 WinVMSize size, 308 WinVMSize size,
292 PointerVector<internal::MemorySnapshotWin>* into) { 309 PointerVector<internal::MemorySnapshotWin>* into) {
293 if (size == 0) 310 if (size == 0)
294 return; 311 return;
295 312
296 // Ensure that the entire range is readable. TODO(scottmg): Consider 313 // Ensure that the entire range is readable. TODO(scottmg): Consider
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 env_block.resize( 394 env_block.resize(
378 static_cast<unsigned int>(bytes_read / sizeof(env_block[0]))); 395 static_cast<unsigned int>(bytes_read / sizeof(env_block[0])));
379 const wchar_t terminator[] = { 0, 0 }; 396 const wchar_t terminator[] = { 0, 0 };
380 size_t at = env_block.find(std::wstring(terminator, arraysize(terminator))); 397 size_t at = env_block.find(std::wstring(terminator, arraysize(terminator)));
381 if (at != std::wstring::npos) 398 if (at != std::wstring::npos)
382 env_block.resize(at + arraysize(terminator)); 399 env_block.resize(at + arraysize(terminator));
383 400
384 return env_block.size() * sizeof(env_block[0]); 401 return env_block.size() * sizeof(env_block[0]);
385 } 402 }
386 403
404 template <class Traits>
405 void ProcessSnapshotWin::ReadLocks(
406 WinVMAddress start,
407 PointerVector<internal::MemorySnapshotWin>* into) {
408 // We're walking the RTL_CRITICAL_SECTION_DEBUG ProcessLocksList, but starting
409 // from an actual RTL_CRITICAL_SECTION, so start by getting to the first
410 // RTL_CRITICAL_SECTION_DEBUG.
411
412 process_types::RTL_CRITICAL_SECTION<Traits> critical_section;
413 if (!process_reader_.ReadMemory(
414 start, sizeof(critical_section), &critical_section)) {
415 LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION";
416 return;
417 }
418
419 const decltype(critical_section.DebugInfo) kInvalid =
420 static_cast<decltype(critical_section.DebugInfo)>(-1);
421 if (critical_section.DebugInfo == kInvalid)
422 return;
423
424 WinVMAddress current = critical_section.DebugInfo;
425 do {
426 // Read the RTL_CRITICAL_SECTION_DEBUG structure to get ProcessLocksList.
427 process_types::RTL_CRITICAL_SECTION_DEBUG<Traits> critical_section_debug;
428 if (!process_reader_.ReadMemory(
429 current, sizeof(critical_section_debug), &critical_section_debug)) {
430 LOG(ERROR) << "failed to read RTL_CRITICAL_SECTION_DEBUG";
431 return;
432 }
433
434 // Add both RTL_CRITICAL_SECTION_DEBUG and RTL_CRITICAL_SECTION_DEBUG to the
Mark Mentovai 2015/10/12 14:08:59 One of these shouldn’t be _DEBUG.
435 // extra memory to be saved.
436 AddMemorySnapshot(current,
437 sizeof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>),
438 into);
439 AddMemorySnapshot(critical_section_debug.CriticalSection,
440 sizeof(process_types::RTL_CRITICAL_SECTION<Traits>),
441 into);
442
443 if (critical_section_debug.ProcessLocksList.Flink == 0)
444 break;
445
446 // Move to the next RTL_CRITICAL_SECTION_DEBUG by walking
447 // ProcessLocksList.Flink.
448 current = critical_section_debug.ProcessLocksList.Flink -
449 offsetof(process_types::RTL_CRITICAL_SECTION_DEBUG<Traits>,
450 ProcessLocksList);
451 } while (current != critical_section.DebugInfo && current != kInvalid);
452 }
453
387 } // namespace crashpad 454 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698