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

Side by Side Diff: components/crash/content/app/crashpad.cc

Issue 2034393004: Allow multiple logging::LogMessage{Handler,Listener}s Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address comments, deque for listeners, reentrant test Created 4 years, 4 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 Chromium Authors. All rights reserved. 1 // Copyright 2015 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/crash/content/app/crashpad.h" 5 #include "components/crash/content/app/crashpad.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <string.h> 8 #include <string.h>
9 9
10 #if BUILDFLAG(ENABLE_KASKO) 10 #if BUILDFLAG(ENABLE_KASKO)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 54
55 void SetCrashKeyValue(const base::StringPiece& key, 55 void SetCrashKeyValue(const base::StringPiece& key,
56 const base::StringPiece& value) { 56 const base::StringPiece& value) {
57 g_simple_string_dictionary->SetKeyValue(key.data(), value.data()); 57 g_simple_string_dictionary->SetKeyValue(key.data(), value.data());
58 } 58 }
59 59
60 void ClearCrashKey(const base::StringPiece& key) { 60 void ClearCrashKey(const base::StringPiece& key) {
61 g_simple_string_dictionary->RemoveKey(key.data()); 61 g_simple_string_dictionary->RemoveKey(key.data());
62 } 62 }
63 63
64 bool LogMessageHandler(int severity, 64 class LogMessageListener : logging::LogMessageListener {
65 const char* file, 65 void OnMessage(int severity,
66 int line, 66 const char* file,
67 size_t message_start, 67 int line,
68 const std::string& string) { 68 size_t message_start,
69 const std::string& string) override;
70 };
71
72 void LogMessageListener::OnMessage(int severity,
73 const char* file,
74 int line,
75 size_t message_start,
76 const std::string& string) {
69 // Only handle FATAL. 77 // Only handle FATAL.
70 if (severity != logging::LOG_FATAL) { 78 if (severity != logging::LOG_FATAL) {
71 return false; 79 return;
72 } 80 }
73 81
74 // In case of an out-of-memory condition, this code could be reentered when 82 // In case of an out-of-memory condition, this code could be reentered when
75 // constructing and storing the key. Using a static is not thread-safe, but if 83 // constructing and storing the key. Using a static is not thread-safe, but if
76 // multiple threads are in the process of a fatal crash at the same time, this 84 // multiple threads are in the process of a fatal crash at the same time, this
77 // should work. 85 // should work.
78 static bool guarded = false; 86 static bool guarded = false;
79 if (guarded) { 87 if (guarded) {
80 return false; 88 return;
81 } 89 }
82 base::AutoReset<bool> guard(&guarded, true); 90 base::AutoReset<bool> guard(&guarded, true);
83 91
84 // Only log last path component. This matches logging.cc. 92 // Only log last path component. This matches logging.cc.
85 if (file) { 93 if (file) {
86 const char* slash = strrchr(file, '/'); 94 const char* slash = strrchr(file, '/');
87 if (slash) { 95 if (slash) {
88 file = slash + 1; 96 file = slash + 1;
89 } 97 }
90 } 98 }
91 99
92 CHECK_LE(message_start, string.size()); 100 CHECK_LE(message_start, string.size());
93 std::string message = base::StringPrintf("%s:%d: %s", file, line, 101 std::string message = base::StringPrintf("%s:%d: %s", file, line,
94 string.c_str() + message_start); 102 string.c_str() + message_start);
95 SetCrashKeyValue("LOG_FATAL", message); 103 SetCrashKeyValue("LOG_FATAL", message);
96 104
97 // Rather than including the code to force the crash here, allow the caller to 105 // Rather than including the code to force the crash here, allow the caller to
98 // do it. 106 // do it.
99 return false;
100 } 107 }
101 108
102 void DumpWithoutCrashing() { 109 void DumpWithoutCrashing() {
103 CRASHPAD_SIMULATE_CRASH(); 110 CRASHPAD_SIMULATE_CRASH();
104 } 111 }
105 112
106 #if BUILDFLAG(ENABLE_KASKO) 113 #if BUILDFLAG(ENABLE_KASKO)
107 // TODO(ananta) 114 // TODO(ananta)
108 // We cannot depend on functionality in base which pulls in dependencies on 115 // We cannot depend on functionality in base which pulls in dependencies on
109 // user32 directly or indirectly. The GetLoadedModulesSnapshot is a copy of the 116 // user32 directly or indirectly. The GetLoadedModulesSnapshot is a copy of the
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 crash_reporter_client->RegisterCrashKeys(); 241 crash_reporter_client->RegisterCrashKeys();
235 242
236 SetCrashKeyValue("ptype", browser_process ? base::StringPiece("browser") 243 SetCrashKeyValue("ptype", browser_process ? base::StringPiece("browser")
237 : base::StringPiece(process_type)); 244 : base::StringPiece(process_type));
238 #if defined(OS_POSIX) 245 #if defined(OS_POSIX)
239 SetCrashKeyValue("pid", base::IntToString(getpid())); 246 SetCrashKeyValue("pid", base::IntToString(getpid()));
240 #elif defined(OS_WIN) 247 #elif defined(OS_WIN)
241 SetCrashKeyValue("pid", base::IntToString(::GetCurrentProcessId())); 248 SetCrashKeyValue("pid", base::IntToString(::GetCurrentProcessId()));
242 #endif 249 #endif
243 250
244 logging::SetLogMessageHandler(LogMessageHandler); 251 // Intentionally leak the listener.
252 auto* listener = new LogMessageListener();
253 CHECK(listener);
brettw 2016/11/14 22:01:31 Ditto
wychen 2016/11/18 21:14:00 Done.
245 254
246 // If clients called CRASHPAD_SIMULATE_CRASH() instead of 255 // If clients called CRASHPAD_SIMULATE_CRASH() instead of
247 // base::debug::DumpWithoutCrashing(), these dumps would appear as crashes in 256 // base::debug::DumpWithoutCrashing(), these dumps would appear as crashes in
248 // the correct function, at the correct file and line. This would be 257 // the correct function, at the correct file and line. This would be
249 // preferable to having all occurrences show up in DumpWithoutCrashing() at 258 // preferable to having all occurrences show up in DumpWithoutCrashing() at
250 // the same file and line. 259 // the same file and line.
251 base::debug::SetDumpWithoutCrashingFunction(DumpWithoutCrashing); 260 base::debug::SetDumpWithoutCrashingFunction(DumpWithoutCrashing);
252 261
253 #if defined(OS_MACOSX) 262 #if defined(OS_MACOSX)
254 // On Mac, we only want the browser to initialize the database, but not the 263 // On Mac, we only want the browser to initialize the database, but not the
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 base::UTF16ToUTF8(value)); 479 base::UTF16ToUTF8(value));
471 } 480 }
472 481
473 void __declspec(dllexport) __cdecl ClearCrashKeyValueImpl(const wchar_t* key) { 482 void __declspec(dllexport) __cdecl ClearCrashKeyValueImpl(const wchar_t* key) {
474 crash_reporter::ClearCrashKey(base::UTF16ToUTF8(key)); 483 crash_reporter::ClearCrashKey(base::UTF16ToUTF8(key));
475 } 484 }
476 485
477 } // extern "C" 486 } // extern "C"
478 487
479 #endif // OS_WIN 488 #endif // OS_WIN
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698