Implement forwarding of search queries for metro mode
[chromium-blink-merge.git] / chrome_frame / crash_reporting / crash_report.cc
blob32c81318c24fd4fbe41407e5fb3193b18ea5887e
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // crash_report.cc : Implementation crash reporting.
6 #include "chrome_frame/crash_reporting/crash_report.h"
8 #include "base/basictypes.h"
9 #include "base/synchronization/lock.h"
10 #include "breakpad/src/client/windows/handler/exception_handler.h"
11 #include "chrome_frame/crash_reporting/crash_metrics.h"
13 // TODO(joshia): factor out common code with chrome used for crash reporting
14 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
16 // This lock protects against concurrent access to g_breakpad.
17 static base::Lock g_breakpad_lock;
18 static google_breakpad::ExceptionHandler* g_breakpad = NULL;
20 // These minidump flag combinations have been tested safe against the
21 // DbgHelp.dll version that ships with Windows XP SP2.
22 const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>(
23 MiniDumpWithProcessThreadData | // Get PEB and TEB.
24 MiniDumpWithUnloadedModules); // Get unloaded modules when available.
26 const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>(
27 MiniDumpWithProcessThreadData | // Get PEB and TEB.
28 MiniDumpWithUnloadedModules | // Get unloaded modules when available.
29 MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by stack.
31 // Large dump with all process memory.
32 const MINIDUMP_TYPE kFullDumpType = static_cast<MINIDUMP_TYPE>(
33 MiniDumpWithFullMemory | // Full memory from process.
34 MiniDumpWithProcessThreadData | // Get PEB and TEB.
35 MiniDumpWithHandleData | // Get all handle information.
36 MiniDumpWithUnloadedModules); // Get unloaded modules when available.
38 #pragma code_seg(push, ".text$va")
39 static void veh_segment_start() {}
40 #pragma code_seg(pop)
42 #pragma code_seg(push, ".text$vz")
43 static void veh_segment_end() {}
44 #pragma code_seg(pop)
46 // Place code in .text$veh_m.
47 #pragma code_seg(push, ".text$vm")
48 #include "chrome_frame/crash_reporting/vectored_handler-impl.h"
50 class CrashHandler {
51 public:
52 CrashHandler() : veh_id_(NULL), handler_(&crash_api_) {}
54 // Note that breakpad_lock is used to protect accesses to breakpad and must
55 // be held when Init() is called.
56 bool Init(google_breakpad::ExceptionHandler* breakpad,
57 base::Lock* breakpad_lock);
59 void Shutdown();
60 private:
61 VectoredHandlerT<CrashHandlerTraits> handler_;
62 CrashHandlerTraits crash_api_;
63 void* veh_id_;
65 static LONG WINAPI VectoredHandlerEntryPoint(EXCEPTION_POINTERS* exptrs);
68 static CrashHandler g_crash_handler;
70 // Turn off FPO optimization, so ::RtlCaptureStackBackTrace returns sane result.
71 #pragma optimize("y", off)
72 LONG WINAPI CrashHandler::VectoredHandlerEntryPoint(
73 EXCEPTION_POINTERS* exptrs) {
74 return g_crash_handler.handler_.Handler(exptrs);
76 #pragma optimize("y", on)
78 #pragma code_seg(pop)
80 bool CrashHandler::Init(google_breakpad::ExceptionHandler* breakpad,
81 base::Lock* breakpad_lock) {
82 DCHECK(breakpad);
83 DCHECK(breakpad_lock);
84 breakpad_lock->AssertAcquired();
86 if (veh_id_)
87 return true;
89 crash_api_.Init(&veh_segment_start, &veh_segment_end,
90 &WriteMinidumpForException);
92 void* id = ::AddVectoredExceptionHandler(FALSE, &VectoredHandlerEntryPoint);
93 if (id != NULL) {
94 veh_id_ = id;
95 return true;
96 } else {
97 crash_api_.Shutdown();
98 return false;
102 void CrashHandler::Shutdown() {
103 if (veh_id_) {
104 ::RemoveVectoredExceptionHandler(veh_id_);
105 veh_id_ = NULL;
108 crash_api_.Shutdown();
111 std::wstring GetCrashServerPipeName(const std::wstring& user_sid) {
112 std::wstring pipe_name = kGoogleUpdatePipeName;
113 pipe_name += user_sid;
114 return pipe_name;
117 bool InitializeVectoredCrashReportingWithPipeName(
118 bool full_dump,
119 const wchar_t* pipe_name,
120 const std::wstring& dump_path,
121 google_breakpad::CustomClientInfo* client_info) {
122 base::AutoLock lock(g_breakpad_lock);
123 if (g_breakpad)
124 return true;
126 if (dump_path.empty()) {
127 return false;
130 // TODO(siggi): Consider switching to kSmallerDumpType post-beta.
131 MINIDUMP_TYPE dump_type = full_dump ? kFullDumpType : kLargerDumpType;
132 g_breakpad = new google_breakpad::ExceptionHandler(
133 dump_path, NULL, NULL, NULL,
134 google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER |
135 google_breakpad::ExceptionHandler::HANDLER_PURECALL, dump_type,
136 pipe_name, client_info);
138 if (!g_breakpad)
139 return false;
141 if (!g_crash_handler.Init(g_breakpad, &g_breakpad_lock)) {
142 delete g_breakpad;
143 g_breakpad = NULL;
144 return false;
147 return true;
150 bool InitializeVectoredCrashReporting(
151 bool full_dump,
152 const wchar_t* user_sid,
153 const std::wstring& dump_path,
154 google_breakpad::CustomClientInfo* client_info) {
155 DCHECK(user_sid);
156 DCHECK(client_info);
158 std::wstring pipe_name = GetCrashServerPipeName(user_sid);
160 return InitializeVectoredCrashReportingWithPipeName(full_dump,
161 pipe_name.c_str(),
162 dump_path,
163 client_info);
166 bool ShutdownVectoredCrashReporting() {
167 g_crash_handler.Shutdown();
168 base::AutoLock lock(g_breakpad_lock);
169 delete g_breakpad;
170 g_breakpad = NULL;
171 return true;
174 bool WriteMinidumpForException(EXCEPTION_POINTERS* p) {
175 base::AutoLock lock(g_breakpad_lock);
176 CrashMetricsReporter::GetInstance()->IncrementMetric(
177 CrashMetricsReporter::CRASH_COUNT);
178 bool success = false;
179 if (g_breakpad) {
180 success = g_breakpad->WriteMinidumpForException(p);
182 return success;