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

Side by Side Diff: chrome/browser/hang_monitor/hang_crash_dump_win.cc

Issue 10983028: Render/pepper hang debugging: generate dumps for the browser and renderer processes if users kill a… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/hang_monitor/hang_crash_dump_win.h" 5 #include "chrome/browser/hang_monitor/hang_crash_dump_win.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "chrome/common/chrome_constants.h" 8 #include "chrome/common/chrome_constants.h"
9 #include "content/public/common/result_codes.h" 9 #include "content/public/common/result_codes.h"
10 #include "ppapi/shared_impl/ppapi_message_tracker.h"
11 10
12 namespace { 11 namespace {
13 12
14 // How long do we wait for the terminated thread or process to die (in ms) 13 // How long do we wait for the terminated thread or process to die (in ms)
15 static const int kTerminateTimeoutMS = 2000; 14 static const int kTerminateTimeoutMS = 2000;
16 15
17 // How long do we wait for the crash to be generated (in ms). 16 // How long do we wait for the crash to be generated (in ms).
18 static const int kGenerateDumpTimeoutMS = 10000; 17 static const int kGenerateDumpTimeoutMS = 10000;
19 18
20 DWORD WINAPI DumpIfHandlingPepper(void*) {
21 typedef void (__cdecl *DumpFunction)();
22 if (ppapi::PpapiMessageTracker::GetInstance()->IsHandlingMessage()) {
23 DumpFunction request_dump = reinterpret_cast<DumpFunction>(GetProcAddress(
24 GetModuleHandle(chrome::kBrowserProcessExecutableName),
25 "DumpProcessWithoutCrash"));
26 DCHECK(request_dump) << "Failed loading DumpProcessWithoutCrash: error " <<
27 GetLastError();
28 if (request_dump)
29 request_dump();
30 }
31 return 0;
32 }
33
34 } // namespace 19 } // namespace
35 20
36 void CrashDumpAndTerminateHungChildProcess(HANDLE hprocess) { 21 void CrashDumpAndTerminateHungChildProcess(HANDLE hprocess) {
37 // Before terminating the process we try collecting a dump. Which 22 // Before terminating the process we try collecting a dump. Which
38 // a transient thread in the child process will do for us. 23 // a transient thread in the child process will do for us.
39 typedef HANDLE (__cdecl *DumpFunction)(HANDLE); 24 typedef HANDLE (__cdecl *DumpFunction)(HANDLE);
40 static DumpFunction request_dump = NULL; 25 static DumpFunction request_dump = NULL;
41 if (!request_dump) { 26 if (!request_dump) {
42 request_dump = reinterpret_cast<DumpFunction>(GetProcAddress( 27 request_dump = reinterpret_cast<DumpFunction>(GetProcAddress(
43 GetModuleHandle(chrome::kBrowserProcessExecutableName), 28 GetModuleHandle(chrome::kBrowserProcessExecutableName),
44 "InjectDumpProcessWithoutCrash")); 29 "InjectDumpProcessWithoutCrash"));
45 DCHECK(request_dump) << "Failed loading DumpProcessWithoutCrash: error " << 30 DCHECK(request_dump) << "Failed loading DumpProcessWithoutCrash: error " <<
46 GetLastError(); 31 GetLastError();
47 } 32 }
48 33
49 if (request_dump) { 34 if (request_dump) {
50 HANDLE remote_thread = request_dump(hprocess); 35 HANDLE remote_thread = request_dump(hprocess);
51 DCHECK(remote_thread) << "Failed creating remote thread: error " << 36 DCHECK(remote_thread) << "Failed creating remote thread: error " <<
52 GetLastError(); 37 GetLastError();
53 if (remote_thread) { 38 if (remote_thread) {
54 WaitForSingleObject(remote_thread, kGenerateDumpTimeoutMS); 39 WaitForSingleObject(remote_thread, kGenerateDumpTimeoutMS);
55 CloseHandle(remote_thread); 40 CloseHandle(remote_thread);
56 } 41 }
57 } 42 }
58 43
59 TerminateProcess(hprocess, content::RESULT_CODE_HUNG); 44 TerminateProcess(hprocess, content::RESULT_CODE_HUNG);
60 WaitForSingleObject(hprocess, kTerminateTimeoutMS); 45 WaitForSingleObject(hprocess, kTerminateTimeoutMS);
61 } 46 }
62 47
63 void CrashDumpIfProcessHandlingPepper(HANDLE hprocess) { 48 void CrashDumpForHangDebugging(HANDLE hprocess) {
64 // Unlike CrashDumpAndTerminateHungChildProcess() which creates a remote 49 if (hprocess == GetCurrentProcess()) {
65 // thread using function pointer relative to chrome.exe, here we create a 50 typedef void (__cdecl *DumpFunction)();
66 // remote thread using function pointer relative to chrome.dll. The reason is 51 DumpFunction request_dump = reinterpret_cast<DumpFunction>(GetProcAddress(
67 // that there are separate PpapiMessageTracker singletons for chrome.dll and 52 GetModuleHandle(chrome::kBrowserProcessExecutableName),
68 // chrome.exe (in non-component build). We cannot access the information 53 "DumpProcessWithoutCrash"));
69 // collected by PpapiMessageTracker of chrome.dll in chrome.exe. 54 DCHECK(request_dump) << "Failed loading DumpProcessWithoutCrash: error " <<
70 // 55 GetLastError();
71 // This is less safe, because chrome.dll may be loaded at different addresses 56 if (request_dump)
72 // in different processes. We could cause crash in that case. However, it 57 request_dump();
73 // should be rare and we are only doing this temporarily for debugging on the 58 } else {
74 // Canary channel. 59 typedef HANDLE (__cdecl *DumpFunction)(HANDLE);
75 HANDLE remote_thread = CreateRemoteThread(hprocess, NULL, 0, 60 DumpFunction request_dump = reinterpret_cast<DumpFunction>(GetProcAddress(
76 DumpIfHandlingPepper, 0, 0, NULL); 61 GetModuleHandle(chrome::kBrowserProcessExecutableName),
77 DCHECK(remote_thread) << "Failed creating remote thread: error " << 62 "InjectDumpForHangDebugging"));
78 GetLastError(); 63 DCHECK(request_dump) << "Failed loading InjectDumpForHangDebugging: error "
79 if (remote_thread) { 64 << GetLastError();
80 WaitForSingleObject(remote_thread, kGenerateDumpTimeoutMS); 65 if (request_dump) {
81 CloseHandle(remote_thread); 66 HANDLE remote_thread = request_dump(hprocess);
67 DCHECK(remote_thread) << "Failed creating remote thread: error " <<
68 GetLastError();
69 if (remote_thread) {
70 WaitForSingleObject(remote_thread, kGenerateDumpTimeoutMS);
71 CloseHandle(remote_thread);
72 }
73 }
82 } 74 }
83 } 75 }
OLDNEW
« no previous file with comments | « chrome/browser/hang_monitor/hang_crash_dump_win.h ('k') | chrome/browser/ui/hung_plugin_tab_helper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698