Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/breakpad/app/breakpad_win.h" | 5 #include "components/breakpad/app/breakpad_win.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <shellapi.h> | 8 #include <shellapi.h> |
| 9 #include <tchar.h> | 9 #include <tchar.h> |
| 10 #include <userenv.h> | 10 #include <userenv.h> |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #include "base/strings/string_util.h" | 26 #include "base/strings/string_util.h" |
| 27 #include "base/strings/stringprintf.h" | 27 #include "base/strings/stringprintf.h" |
| 28 #include "base/strings/utf_string_conversions.h" | 28 #include "base/strings/utf_string_conversions.h" |
| 29 #include "base/synchronization/lock.h" | 29 #include "base/synchronization/lock.h" |
| 30 #include "base/win/metro.h" | 30 #include "base/win/metro.h" |
| 31 #include "base/win/pe_image.h" | 31 #include "base/win/pe_image.h" |
| 32 #include "base/win/registry.h" | 32 #include "base/win/registry.h" |
| 33 #include "base/win/win_util.h" | 33 #include "base/win/win_util.h" |
| 34 #include "breakpad/src/client/windows/handler/exception_handler.h" | 34 #include "breakpad/src/client/windows/handler/exception_handler.h" |
| 35 #include "components/breakpad/app/breakpad_client.h" | 35 #include "components/breakpad/app/breakpad_client.h" |
| 36 #include "components/breakpad/app/crash_keys_win.h" | |
| 36 #include "components/breakpad/app/hard_error_handler_win.h" | 37 #include "components/breakpad/app/hard_error_handler_win.h" |
| 37 #include "content/public/common/result_codes.h" | 38 #include "content/public/common/result_codes.h" |
| 38 #include "sandbox/win/src/nt_internals.h" | 39 #include "sandbox/win/src/nt_internals.h" |
| 39 #include "sandbox/win/src/sidestep/preamble_patcher.h" | 40 #include "sandbox/win/src/sidestep/preamble_patcher.h" |
| 40 | 41 |
| 41 // userenv.dll is required for GetProfileType(). | 42 // userenv.dll is required for GetProfileType(). |
| 42 #pragma comment(lib, "userenv.lib") | 43 #pragma comment(lib, "userenv.lib") |
| 43 | 44 |
| 44 #pragma intrinsic(_AddressOfReturnAddress) | 45 #pragma intrinsic(_AddressOfReturnAddress) |
| 45 #pragma intrinsic(_ReturnAddress) | 46 #pragma intrinsic(_ReturnAddress) |
| 46 | 47 |
| 47 namespace breakpad { | 48 namespace breakpad { |
| 48 | 49 |
| 49 // Manages the breakpad key/value pair stash, there may only be one instance | |
| 50 // of this class per process at one time. | |
| 51 class CrashKeysWin { | |
| 52 public: | |
| 53 CrashKeysWin(); | |
| 54 ~CrashKeysWin(); | |
| 55 | |
| 56 // May only be called once. | |
| 57 google_breakpad::CustomClientInfo* | |
| 58 GetCustomInfo(const std::wstring& exe_path, const std::wstring& type); | |
| 59 | |
| 60 void SetCrashKeyValue(const std::wstring& key, const std::wstring& value); | |
| 61 void ClearCrashKeyValue(const std::wstring& key); | |
| 62 | |
| 63 static CrashKeysWin* keeper() { return keeper_; } | |
| 64 | |
| 65 private: | |
| 66 // One-time initialization of private key/value pairs. | |
| 67 void SetPluginPath(const std::wstring& path); | |
| 68 void SetBreakpadDumpPath(); | |
| 69 | |
| 70 // Must not be resized after GetCustomInfo is invoked. | |
| 71 std::vector<google_breakpad::CustomInfoEntry> custom_entries_; | |
| 72 | |
| 73 typedef std::map<std::wstring, google_breakpad::CustomInfoEntry*> | |
| 74 DynamicEntriesMap; | |
| 75 base::Lock lock_; | |
| 76 // Keeps track of the next index for a new dynamic entry. | |
| 77 size_t dynamic_keys_offset_; // Under lock_. | |
| 78 // Maintains key->entry information for dynamic key/value entries | |
| 79 // in custom_entries_. | |
| 80 DynamicEntriesMap dynamic_entries_; // Under lock_. | |
| 81 | |
| 82 // Stores the sole instance of this class allowed per process. | |
| 83 static CrashKeysWin* keeper_; | |
| 84 }; | |
| 85 | |
| 86 CrashKeysWin* CrashKeysWin::keeper_; | |
| 87 | |
| 88 CrashKeysWin::CrashKeysWin() : dynamic_keys_offset_(0) { | |
| 89 DCHECK_EQ(static_cast<CrashKeysWin*>(NULL), keeper_); | |
| 90 keeper_ = this; | |
| 91 } | |
| 92 | |
| 93 CrashKeysWin::~CrashKeysWin() { | |
| 94 DCHECK_EQ(this, keeper_); | |
| 95 keeper_ = NULL; | |
| 96 } | |
| 97 | |
| 98 namespace { | 50 namespace { |
| 99 | 51 |
| 100 // Minidump with stacks, PEB, TEB, and unloaded module list. | 52 // Minidump with stacks, PEB, TEB, and unloaded module list. |
| 101 const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>( | 53 const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>( |
| 102 MiniDumpWithProcessThreadData | // Get PEB and TEB. | 54 MiniDumpWithProcessThreadData | // Get PEB and TEB. |
| 103 MiniDumpWithUnloadedModules); // Get unloaded modules when available. | 55 MiniDumpWithUnloadedModules); // Get unloaded modules when available. |
| 104 | 56 |
| 105 // Minidump with all of the above, plus memory referenced from stack. | 57 // Minidump with all of the above, plus memory referenced from stack. |
| 106 const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>( | 58 const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>( |
| 107 MiniDumpWithProcessThreadData | // Get PEB and TEB. | 59 MiniDumpWithProcessThreadData | // Get PEB and TEB. |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 130 EXCEPTION_RECORD g_surrogate_exception_record = {0}; | 82 EXCEPTION_RECORD g_surrogate_exception_record = {0}; |
| 131 CONTEXT g_surrogate_context = {0}; | 83 CONTEXT g_surrogate_context = {0}; |
| 132 | 84 |
| 133 typedef NTSTATUS (WINAPI* NtTerminateProcessPtr)(HANDLE ProcessHandle, | 85 typedef NTSTATUS (WINAPI* NtTerminateProcessPtr)(HANDLE ProcessHandle, |
| 134 NTSTATUS ExitStatus); | 86 NTSTATUS ExitStatus); |
| 135 char* g_real_terminate_process_stub = NULL; | 87 char* g_real_terminate_process_stub = NULL; |
| 136 | 88 |
| 137 | 89 |
| 138 // Allow for 256 dynamic entries in addition to the fixed set of entries | 90 // Allow for 256 dynamic entries in addition to the fixed set of entries |
| 139 // set up in this file. | 91 // set up in this file. |
| 140 const size_t kMaxDynamicEntries = 256; | 92 const size_t kMaxDynamicEntries = 256; |
|
erikwright (departed)
2014/06/11 13:27:47
Are these two constants still needed here? If so,
Sigurður Ásgeirsson
2014/06/11 13:55:26
Thanks, removed.
| |
| 141 | 93 |
| 142 // Maximum length for plugin path to include in plugin crash reports. | 94 // Maximum length for plugin path to include in plugin crash reports. |
| 143 const size_t kMaxPluginPathLength = 256; | 95 const size_t kMaxPluginPathLength = 256; |
| 144 | 96 |
| 145 } // namespace | 97 } // namespace |
| 146 | 98 |
| 147 // Dumps the current process memory. | 99 // Dumps the current process memory. |
| 148 extern "C" void __declspec(dllexport) __cdecl DumpProcess() { | 100 extern "C" void __declspec(dllexport) __cdecl DumpProcess() { |
| 149 if (g_breakpad) { | 101 if (g_breakpad) { |
| 150 g_breakpad->WriteMinidump(); | 102 g_breakpad->WriteMinidump(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 194 return CreateRemoteThread(process, NULL, 0, DumpProcessWithoutCrashThread, | 146 return CreateRemoteThread(process, NULL, 0, DumpProcessWithoutCrashThread, |
| 195 0, 0, NULL); | 147 0, 0, NULL); |
| 196 } | 148 } |
| 197 | 149 |
| 198 extern "C" HANDLE __declspec(dllexport) __cdecl | 150 extern "C" HANDLE __declspec(dllexport) __cdecl |
| 199 InjectDumpForHangDebugging(HANDLE process) { | 151 InjectDumpForHangDebugging(HANDLE process) { |
| 200 return CreateRemoteThread(process, NULL, 0, DumpForHangDebuggingThread, | 152 return CreateRemoteThread(process, NULL, 0, DumpForHangDebuggingThread, |
| 201 0, 0, NULL); | 153 0, 0, NULL); |
| 202 } | 154 } |
| 203 | 155 |
| 204 // Appends the plugin path to |g_custom_entries|. | |
| 205 void CrashKeysWin::SetPluginPath(const std::wstring& path) { | |
| 206 if (path.size() > kMaxPluginPathLength) { | |
| 207 // If the path is too long, truncate from the start rather than the end, | |
| 208 // since we want to be able to recover the DLL name. | |
| 209 SetPluginPath(path.substr(path.size() - kMaxPluginPathLength)); | |
| 210 return; | |
| 211 } | |
| 212 | |
| 213 // The chunk size without terminator. | |
| 214 const size_t kChunkSize = static_cast<size_t>( | |
| 215 google_breakpad::CustomInfoEntry::kValueMaxLength - 1); | |
| 216 | |
| 217 int chunk_index = 0; | |
| 218 size_t chunk_start = 0; // Current position inside |path| | |
| 219 | |
| 220 for (chunk_start = 0; chunk_start < path.size(); chunk_index++) { | |
| 221 size_t chunk_length = std::min(kChunkSize, path.size() - chunk_start); | |
| 222 | |
| 223 custom_entries_.push_back(google_breakpad::CustomInfoEntry( | |
| 224 base::StringPrintf(L"plugin-path-chunk-%i", chunk_index + 1).c_str(), | |
| 225 path.substr(chunk_start, chunk_length).c_str())); | |
| 226 | |
| 227 chunk_start += chunk_length; | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 // Appends the breakpad dump path to |g_custom_entries|. | |
| 232 void CrashKeysWin::SetBreakpadDumpPath() { | |
| 233 base::FilePath crash_dumps_dir_path; | |
| 234 if (GetBreakpadClient()->GetAlternativeCrashDumpLocation( | |
| 235 &crash_dumps_dir_path)) { | |
| 236 custom_entries_.push_back(google_breakpad::CustomInfoEntry( | |
| 237 L"breakpad-dump-location", crash_dumps_dir_path.value().c_str())); | |
| 238 } | |
| 239 } | |
| 240 | |
| 241 // Returns a string containing a list of all modifiers for the loaded profile. | 156 // Returns a string containing a list of all modifiers for the loaded profile. |
| 242 std::wstring GetProfileType() { | 157 std::wstring GetProfileType() { |
| 243 std::wstring profile_type; | 158 std::wstring profile_type; |
| 244 DWORD profile_bits = 0; | 159 DWORD profile_bits = 0; |
| 245 if (::GetProfileType(&profile_bits)) { | 160 if (::GetProfileType(&profile_bits)) { |
| 246 static const struct { | 161 static const struct { |
| 247 DWORD bit; | 162 DWORD bit; |
| 248 const wchar_t* name; | 163 const wchar_t* name; |
| 249 } kBitNames[] = { | 164 } kBitNames[] = { |
| 250 { PT_MANDATORY, L"mandatory" }, | 165 { PT_MANDATORY, L"mandatory" }, |
| 251 { PT_ROAMING, L"roaming" }, | 166 { PT_ROAMING, L"roaming" }, |
| 252 { PT_TEMPORARY, L"temporary" }, | 167 { PT_TEMPORARY, L"temporary" }, |
| 253 }; | 168 }; |
| 254 for (size_t i = 0; i < arraysize(kBitNames); ++i) { | 169 for (size_t i = 0; i < arraysize(kBitNames); ++i) { |
| 255 const DWORD this_bit = kBitNames[i].bit; | 170 const DWORD this_bit = kBitNames[i].bit; |
| 256 if ((profile_bits & this_bit) != 0) { | 171 if ((profile_bits & this_bit) != 0) { |
| 257 profile_type.append(kBitNames[i].name); | 172 profile_type.append(kBitNames[i].name); |
| 258 profile_bits &= ~this_bit; | 173 profile_bits &= ~this_bit; |
| 259 if (profile_bits != 0) | 174 if (profile_bits != 0) |
| 260 profile_type.append(L", "); | 175 profile_type.append(L", "); |
| 261 } | 176 } |
| 262 } | 177 } |
| 263 } else { | 178 } else { |
| 264 DWORD last_error = ::GetLastError(); | 179 DWORD last_error = ::GetLastError(); |
| 265 base::SStringPrintf(&profile_type, L"error %u", last_error); | 180 base::SStringPrintf(&profile_type, L"error %u", last_error); |
| 266 } | 181 } |
| 267 return profile_type; | 182 return profile_type; |
| 268 } | 183 } |
| 269 | 184 |
| 270 // Returns the custom info structure based on the dll in parameter and the | |
| 271 // process type. | |
| 272 google_breakpad::CustomClientInfo* | |
| 273 CrashKeysWin::GetCustomInfo(const std::wstring& exe_path, | |
| 274 const std::wstring& type) { | |
| 275 base::string16 version, product; | |
| 276 base::string16 special_build; | |
| 277 base::string16 channel_name; | |
| 278 GetBreakpadClient()->GetProductNameAndVersion( | |
| 279 base::FilePath(exe_path), | |
| 280 &product, | |
| 281 &version, | |
| 282 &special_build, | |
| 283 &channel_name); | |
| 284 | |
| 285 // We only expect this method to be called once per process. | |
| 286 // Common enties | |
| 287 custom_entries_.push_back( | |
| 288 google_breakpad::CustomInfoEntry(L"ver", version.c_str())); | |
| 289 custom_entries_.push_back( | |
| 290 google_breakpad::CustomInfoEntry(L"prod", product.c_str())); | |
| 291 custom_entries_.push_back( | |
| 292 google_breakpad::CustomInfoEntry(L"plat", L"Win32")); | |
| 293 custom_entries_.push_back( | |
| 294 google_breakpad::CustomInfoEntry(L"ptype", type.c_str())); | |
| 295 custom_entries_.push_back(google_breakpad::CustomInfoEntry( | |
| 296 L"pid", base::StringPrintf(L"%d", ::GetCurrentProcessId()).c_str())); | |
| 297 custom_entries_.push_back(google_breakpad::CustomInfoEntry( | |
| 298 L"channel", channel_name.c_str())); | |
| 299 custom_entries_.push_back(google_breakpad::CustomInfoEntry( | |
| 300 L"profile-type", GetProfileType().c_str())); | |
| 301 | |
| 302 if (!special_build.empty()) { | |
| 303 custom_entries_.push_back(google_breakpad::CustomInfoEntry( | |
| 304 L"special", special_build.c_str())); | |
| 305 } | |
| 306 | |
| 307 if (type == L"plugin" || type == L"ppapi") { | |
| 308 std::wstring plugin_path = | |
| 309 CommandLine::ForCurrentProcess()->GetSwitchValueNative("plugin-path"); | |
| 310 if (!plugin_path.empty()) | |
| 311 SetPluginPath(plugin_path); | |
| 312 } | |
| 313 | |
| 314 // Check whether configuration management controls crash reporting. | |
| 315 bool crash_reporting_enabled = true; | |
| 316 bool controlled_by_policy = GetBreakpadClient()->ReportingIsEnforcedByPolicy( | |
| 317 &crash_reporting_enabled); | |
| 318 const CommandLine& command = *CommandLine::ForCurrentProcess(); | |
| 319 bool use_crash_service = | |
| 320 !controlled_by_policy && (command.HasSwitch(switches::kNoErrorDialogs) || | |
| 321 GetBreakpadClient()->IsRunningUnattended()); | |
| 322 if (use_crash_service) | |
| 323 SetBreakpadDumpPath(); | |
| 324 | |
| 325 // Create space for dynamic ad-hoc keys. The names and values are set using | |
| 326 // the API defined in base/debug/crash_logging.h. | |
| 327 dynamic_keys_offset_ = custom_entries_.size(); | |
| 328 for (size_t i = 0; i < kMaxDynamicEntries; ++i) { | |
| 329 // The names will be mutated as they are set. Un-numbered since these are | |
| 330 // merely placeholders. The name cannot be empty because Breakpad's | |
| 331 // HTTPUpload will interpret that as an invalid parameter. | |
| 332 custom_entries_.push_back( | |
| 333 google_breakpad::CustomInfoEntry(L"unspecified-crash-key", L"")); | |
| 334 } | |
| 335 | |
| 336 static google_breakpad::CustomClientInfo custom_client_info; | |
| 337 custom_client_info.entries = &custom_entries_.front(); | |
| 338 custom_client_info.count = custom_entries_.size(); | |
| 339 | |
| 340 return &custom_client_info; | |
| 341 } | |
| 342 | |
| 343 namespace { | 185 namespace { |
| 344 | 186 |
| 345 // This callback is used when we want to get a dump without crashing the | 187 // This callback is used when we want to get a dump without crashing the |
| 346 // process. | 188 // process. |
| 347 bool DumpDoneCallbackWhenNoCrash(const wchar_t*, const wchar_t*, void*, | 189 bool DumpDoneCallbackWhenNoCrash(const wchar_t*, const wchar_t*, void*, |
| 348 EXCEPTION_POINTERS* ex_info, | 190 EXCEPTION_POINTERS* ex_info, |
| 349 MDRawAssertionInfo*, bool) { | 191 MDRawAssertionInfo*, bool) { |
| 350 return true; | 192 return true; |
| 351 } | 193 } |
| 352 | 194 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 // Exception filter for the service process used when breakpad is not enabled. | 268 // Exception filter for the service process used when breakpad is not enabled. |
| 427 // We just display the "Do you want to restart" message and then die | 269 // We just display the "Do you want to restart" message and then die |
| 428 // (without calling the previous filter). | 270 // (without calling the previous filter). |
| 429 long WINAPI ServiceExceptionFilter(EXCEPTION_POINTERS* info) { | 271 long WINAPI ServiceExceptionFilter(EXCEPTION_POINTERS* info) { |
| 430 DumpDoneCallback(NULL, NULL, NULL, info, NULL, false); | 272 DumpDoneCallback(NULL, NULL, NULL, info, NULL, false); |
| 431 return EXCEPTION_EXECUTE_HANDLER; | 273 return EXCEPTION_EXECUTE_HANDLER; |
| 432 } | 274 } |
| 433 | 275 |
| 434 } // namespace | 276 } // namespace |
| 435 | 277 |
| 436 void CrashKeysWin::SetCrashKeyValue( | |
| 437 const std::wstring& key, const std::wstring& value) { | |
| 438 // CustomInfoEntry limits the length of key and value. If they exceed | |
| 439 // their maximum length the underlying string handling functions raise | |
| 440 // an exception and prematurely trigger a crash. Truncate here. | |
| 441 std::wstring safe_key(std::wstring(key).substr( | |
| 442 0, google_breakpad::CustomInfoEntry::kNameMaxLength - 1)); | |
| 443 std::wstring safe_value(std::wstring(value).substr( | |
| 444 0, google_breakpad::CustomInfoEntry::kValueMaxLength - 1)); | |
| 445 | |
| 446 // If we already have a value for this key, update it; otherwise, insert | |
| 447 // the new value if we have not exhausted the pre-allocated slots for dynamic | |
| 448 // entries. | |
| 449 base::AutoLock lock(lock_); | |
| 450 | |
| 451 DynamicEntriesMap::iterator it = dynamic_entries_.find(safe_key); | |
| 452 google_breakpad::CustomInfoEntry* entry = NULL; | |
| 453 if (it == dynamic_entries_.end()) { | |
| 454 if (dynamic_entries_.size() >= kMaxDynamicEntries) | |
| 455 return; | |
| 456 entry = &custom_entries_[dynamic_keys_offset_++]; | |
| 457 dynamic_entries_.insert(std::make_pair(safe_key, entry)); | |
| 458 } else { | |
| 459 entry = it->second; | |
| 460 } | |
| 461 | |
| 462 entry->set(safe_key.data(), safe_value.data()); | |
| 463 } | |
| 464 | |
| 465 // NOTE: This function is used by SyzyASAN to annotate crash reports. If you | 278 // NOTE: This function is used by SyzyASAN to annotate crash reports. If you |
| 466 // change the name or signature of this function you will break SyzyASAN | 279 // change the name or signature of this function you will break SyzyASAN |
| 467 // instrumented releases of Chrome. Please contact syzygy-team@chromium.org | 280 // instrumented releases of Chrome. Please contact syzygy-team@chromium.org |
| 468 // before doing so! | 281 // before doing so! |
| 469 extern "C" void __declspec(dllexport) __cdecl SetCrashKeyValueImpl( | 282 extern "C" void __declspec(dllexport) __cdecl SetCrashKeyValueImpl( |
| 470 const wchar_t* key, const wchar_t* value) { | 283 const wchar_t* key, const wchar_t* value) { |
| 471 CrashKeysWin* keeper = CrashKeysWin::keeper(); | 284 CrashKeysWin* keeper = CrashKeysWin::keeper(); |
| 472 if (!keeper) | 285 if (!keeper) |
| 473 return; | 286 return; |
| 474 | 287 |
| 475 // TODO(siggi): This doesn't look quite right - there's NULL deref potential | 288 // TODO(siggi): This doesn't look quite right - there's NULL deref potential |
| 476 // here, and an implicit std::wstring conversion. Fixme. | 289 // here, and an implicit std::wstring conversion. Fixme. |
| 477 keeper->SetCrashKeyValue(key, value); | 290 keeper->SetCrashKeyValue(key, value); |
| 478 } | 291 } |
| 479 | 292 |
| 480 void CrashKeysWin::ClearCrashKeyValue(const std::wstring& key) { | |
| 481 base::AutoLock lock(lock_); | |
| 482 | |
| 483 std::wstring key_string(key); | |
| 484 DynamicEntriesMap::iterator it = dynamic_entries_.find(key_string); | |
| 485 if (it == dynamic_entries_.end()) | |
| 486 return; | |
| 487 | |
| 488 it->second->set_value(NULL); | |
| 489 } | |
| 490 | |
| 491 extern "C" void __declspec(dllexport) __cdecl ClearCrashKeyValueImpl( | 293 extern "C" void __declspec(dllexport) __cdecl ClearCrashKeyValueImpl( |
| 492 const wchar_t* key) { | 294 const wchar_t* key) { |
| 493 CrashKeysWin* keeper = CrashKeysWin::keeper(); | 295 CrashKeysWin* keeper = CrashKeysWin::keeper(); |
| 494 if (!keeper) | 296 if (!keeper) |
| 495 return; | 297 return; |
| 496 | 298 |
| 497 // TODO(siggi): This doesn't look quite right - there's NULL deref potential | 299 // TODO(siggi): This doesn't look quite right - there's NULL deref potential |
| 498 // here, and an implicit std::wstring conversion. Fixme. | 300 // here, and an implicit std::wstring conversion. Fixme. |
| 499 keeper->ClearCrashKeyValue(key); | 301 keeper->ClearCrashKeyValue(key); |
| 500 } | 302 } |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 702 exe_path[0] = 0; | 504 exe_path[0] = 0; |
| 703 GetModuleFileNameW(NULL, exe_path, MAX_PATH); | 505 GetModuleFileNameW(NULL, exe_path, MAX_PATH); |
| 704 | 506 |
| 705 bool is_per_user_install = | 507 bool is_per_user_install = |
| 706 GetBreakpadClient()->GetIsPerUserInstall(base::FilePath(exe_path)); | 508 GetBreakpadClient()->GetIsPerUserInstall(base::FilePath(exe_path)); |
| 707 | 509 |
| 708 // This is intentionally leaked. | 510 // This is intentionally leaked. |
| 709 CrashKeysWin* keeper = new CrashKeysWin(); | 511 CrashKeysWin* keeper = new CrashKeysWin(); |
| 710 | 512 |
| 711 google_breakpad::CustomClientInfo* custom_info = | 513 google_breakpad::CustomClientInfo* custom_info = |
| 712 keeper->GetCustomInfo(exe_path, process_type); | 514 keeper->GetCustomInfo(exe_path, process_type, |
| 515 GetProfileType(), CommandLine::ForCurrentProcess(), | |
| 516 GetBreakpadClient()); | |
| 713 | 517 |
| 714 google_breakpad::ExceptionHandler::MinidumpCallback callback = NULL; | 518 google_breakpad::ExceptionHandler::MinidumpCallback callback = NULL; |
| 715 LPTOP_LEVEL_EXCEPTION_FILTER default_filter = NULL; | 519 LPTOP_LEVEL_EXCEPTION_FILTER default_filter = NULL; |
| 716 // We install the post-dump callback only for the browser and service | 520 // We install the post-dump callback only for the browser and service |
| 717 // processes. It spawns a new browser/service process. | 521 // processes. It spawns a new browser/service process. |
| 718 if (process_type == L"browser") { | 522 if (process_type == L"browser") { |
| 719 callback = &DumpDoneCallback; | 523 callback = &DumpDoneCallback; |
| 720 default_filter = &ChromeExceptionFilter; | 524 default_filter = &ChromeExceptionFilter; |
| 721 } else if (process_type == L"service") { | 525 } else if (process_type == L"service") { |
| 722 callback = &DumpDoneCallback; | 526 callback = &DumpDoneCallback; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 789 if (process_type != L"browser" && | 593 if (process_type != L"browser" && |
| 790 !GetBreakpadClient()->IsRunningUnattended()) { | 594 !GetBreakpadClient()->IsRunningUnattended()) { |
| 791 // Initialize the hook TerminateProcess to catch unexpected exits. | 595 // Initialize the hook TerminateProcess to catch unexpected exits. |
| 792 InitTerminateProcessHooks(); | 596 InitTerminateProcessHooks(); |
| 793 } | 597 } |
| 794 #endif | 598 #endif |
| 795 } | 599 } |
| 796 } | 600 } |
| 797 | 601 |
| 798 } // namespace breakpad | 602 } // namespace breakpad |
| OLD | NEW |