OLD | NEW |
---|---|
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 "base/logging.h" | 5 #include "base/logging.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <io.h> | 8 #include <io.h> |
9 #include <windows.h> | 9 #include <windows.h> |
10 typedef HANDLE FileHandle; | 10 typedef HANDLE FileHandle; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 | 73 |
74 void set_dcheck_state(DcheckState state) { | 74 void set_dcheck_state(DcheckState state) { |
75 g_dcheck_state = state; | 75 g_dcheck_state = state; |
76 } | 76 } |
77 | 77 |
78 namespace { | 78 namespace { |
79 | 79 |
80 VlogInfo* g_vlog_info = NULL; | 80 VlogInfo* g_vlog_info = NULL; |
81 VlogInfo* g_vlog_info_prev = NULL; | 81 VlogInfo* g_vlog_info_prev = NULL; |
82 | 82 |
83 const char* const log_severity_names[LOG_NUM_SEVERITIES] = { | 83 const char* const kLogSeverityNames[LOG_NUM_SEVERITIES] = { |
84 "INFO", "WARNING", "ERROR", "ERROR_REPORT", "FATAL" }; | 84 "INFO", "WARNING", "ERROR", "ERROR_REPORT", "FATAL" }; |
85 | 85 |
86 int min_log_level = 0; | 86 int g_min_log_level = 0; |
brettw
2013/06/19 18:10:13
This stuff is in an anonymous namespace in a .cc f
akalin
2013/06/19 19:59:18
Done. There were already some existing g_ variable
| |
87 | 87 |
88 // The default set here for logging_destination will only be used if | 88 LoggingDestination g_logging_destination = LOG_DEFAULT; |
89 // InitLogging is not called. On Windows, use a file next to the exe; | |
90 // on POSIX platforms, where it may not even be possible to locate the | |
91 // executable on disk, use stderr. | |
92 #if defined(OS_WIN) | |
93 LoggingDestination logging_destination = LOG_ONLY_TO_FILE; | |
94 #elif defined(OS_POSIX) | |
95 LoggingDestination logging_destination = LOG_ONLY_TO_SYSTEM_DEBUG_LOG; | |
96 #endif | |
97 | 89 |
98 // For LOG_ERROR and above, always print to stderr. | 90 // For LOG_ERROR and above, always print to stderr. |
99 const int kAlwaysPrintErrorLevel = LOG_ERROR; | 91 const int kAlwaysPrintErrorLevel = LOG_ERROR; |
100 | 92 |
101 // Which log file to use? This is initialized by InitLogging or | 93 // Which log file to use? This is initialized by InitLogging or |
102 // will be lazily initialized to the default value when it is | 94 // will be lazily initialized to the default value when it is |
103 // first needed. | 95 // first needed. |
104 #if defined(OS_WIN) | 96 #if defined(OS_WIN) |
105 typedef std::wstring PathString; | 97 typedef std::wstring PathString; |
106 #else | 98 #else |
107 typedef std::string PathString; | 99 typedef std::string PathString; |
108 #endif | 100 #endif |
109 PathString* log_file_name = NULL; | 101 PathString* g_log_file_name = NULL; |
110 | 102 |
111 // this file is lazily opened and the handle may be NULL | 103 // this file is lazily opened and the handle may be NULL |
112 FileHandle log_file = NULL; | 104 FileHandle g_log_file = NULL; |
113 | 105 |
114 // what should be prepended to each message? | 106 // what should be prepended to each message? |
115 bool log_process_id = false; | 107 bool g_log_process_id = false; |
116 bool log_thread_id = false; | 108 bool g_log_thread_id = false; |
117 bool log_timestamp = true; | 109 bool g_log_timestamp = true; |
118 bool log_tickcount = false; | 110 bool g_log_tickcount = false; |
119 | 111 |
120 // Should we pop up fatal debug messages in a dialog? | 112 // Should we pop up fatal debug messages in a dialog? |
121 bool show_error_dialogs = false; | 113 bool g_show_error_dialogs = false; |
122 | 114 |
123 // An assert handler override specified by the client to be called instead of | 115 // An assert handler override specified by the client to be called instead of |
124 // the debug message dialog and process termination. | 116 // the debug message dialog and process termination. |
125 LogAssertHandlerFunction log_assert_handler = NULL; | 117 LogAssertHandlerFunction g_log_assert_handler = NULL; |
126 // An report handler override specified by the client to be called instead of | 118 // An report handler override specified by the client to be called instead of |
127 // the debug message dialog. | 119 // the debug message dialog. |
128 LogReportHandlerFunction log_report_handler = NULL; | 120 LogReportHandlerFunction g_log_report_handler = NULL; |
129 // A log message handler that gets notified of every log message we process. | 121 // A log message handler that gets notified of every log message we process. |
130 LogMessageHandlerFunction log_message_handler = NULL; | 122 LogMessageHandlerFunction g_log_message_handler = NULL; |
131 | 123 |
132 // Helper functions to wrap platform differences. | 124 // Helper functions to wrap platform differences. |
133 | 125 |
134 int32 CurrentProcessId() { | 126 int32 CurrentProcessId() { |
135 #if defined(OS_WIN) | 127 #if defined(OS_WIN) |
136 return GetCurrentProcessId(); | 128 return GetCurrentProcessId(); |
137 #elif defined(OS_POSIX) | 129 #elif defined(OS_POSIX) |
138 return getpid(); | 130 return getpid(); |
139 #endif | 131 #endif |
140 } | 132 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
177 unlink(log_name.c_str()); | 169 unlink(log_name.c_str()); |
178 #endif | 170 #endif |
179 } | 171 } |
180 | 172 |
181 PathString GetDefaultLogFile() { | 173 PathString GetDefaultLogFile() { |
182 #if defined(OS_WIN) | 174 #if defined(OS_WIN) |
183 // On Windows we use the same path as the exe. | 175 // On Windows we use the same path as the exe. |
184 wchar_t module_name[MAX_PATH]; | 176 wchar_t module_name[MAX_PATH]; |
185 GetModuleFileName(NULL, module_name, MAX_PATH); | 177 GetModuleFileName(NULL, module_name, MAX_PATH); |
186 | 178 |
187 PathString log_file = module_name; | 179 PathString g_log_file = module_name; |
188 PathString::size_type last_backslash = | 180 PathString::size_type last_backslash = |
189 log_file.rfind('\\', log_file.size()); | 181 g_log_file.rfind('\\', g_log_file.size()); |
190 if (last_backslash != PathString::npos) | 182 if (last_backslash != PathString::npos) |
191 log_file.erase(last_backslash + 1); | 183 g_log_file.erase(last_backslash + 1); |
192 log_file += L"debug.log"; | 184 g_log_file += L"debug.log"; |
193 return log_file; | 185 return g_log_file; |
194 #elif defined(OS_POSIX) | 186 #elif defined(OS_POSIX) |
195 // On other platforms we just use the current directory. | 187 // On other platforms we just use the current directory. |
196 return PathString("debug.log"); | 188 return PathString("debug.log"); |
197 #endif | 189 #endif |
198 } | 190 } |
199 | 191 |
200 // This class acts as a wrapper for locking the logging files. | 192 // This class acts as a wrapper for locking the logging files. |
201 // LoggingLock::Init() should be called from the main thread before any logging | 193 // LoggingLock::Init() should be called from the main thread before any logging |
202 // is done. Then whenever logging, be sure to have a local LoggingLock | 194 // is done. Then whenever logging, be sure to have a local LoggingLock |
203 // instance on the stack. This will ensure that the lock is unlocked upon | 195 // instance on the stack. This will ensure that the lock is unlocked upon |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
307 // static | 299 // static |
308 MutexHandle LoggingLock::log_mutex = NULL; | 300 MutexHandle LoggingLock::log_mutex = NULL; |
309 #elif defined(OS_POSIX) | 301 #elif defined(OS_POSIX) |
310 pthread_mutex_t LoggingLock::log_mutex = PTHREAD_MUTEX_INITIALIZER; | 302 pthread_mutex_t LoggingLock::log_mutex = PTHREAD_MUTEX_INITIALIZER; |
311 #endif | 303 #endif |
312 | 304 |
313 // Called by logging functions to ensure that debug_file is initialized | 305 // Called by logging functions to ensure that debug_file is initialized |
314 // and can be used for writing. Returns false if the file could not be | 306 // and can be used for writing. Returns false if the file could not be |
315 // initialized. debug_file will be NULL in this case. | 307 // initialized. debug_file will be NULL in this case. |
316 bool InitializeLogFileHandle() { | 308 bool InitializeLogFileHandle() { |
317 if (log_file) | 309 if (g_log_file) |
318 return true; | 310 return true; |
319 | 311 |
320 if (!log_file_name) { | 312 if (!g_log_file_name) { |
321 // Nobody has called InitLogging to specify a debug log file, so here we | 313 // Nobody has called InitLogging to specify a debug log file, so here we |
322 // initialize the log file name to a default. | 314 // initialize the log file name to a default. |
323 log_file_name = new PathString(GetDefaultLogFile()); | 315 g_log_file_name = new PathString(GetDefaultLogFile()); |
324 } | 316 } |
325 | 317 |
326 if (logging_destination == LOG_ONLY_TO_FILE || | 318 if ((g_logging_destination & LOG_TO_FILE) != 0) { |
327 logging_destination == LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) { | |
328 #if defined(OS_WIN) | 319 #if defined(OS_WIN) |
329 log_file = CreateFile(log_file_name->c_str(), GENERIC_WRITE, | 320 g_log_file = CreateFile(g_log_file_name->c_str(), GENERIC_WRITE, |
330 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | |
331 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | |
332 if (log_file == INVALID_HANDLE_VALUE || log_file == NULL) { | |
333 // try the current directory | |
334 log_file = CreateFile(L".\\debug.log", GENERIC_WRITE, | |
335 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | 321 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, |
336 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | 322 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
337 if (log_file == INVALID_HANDLE_VALUE || log_file == NULL) { | 323 if (g_log_file == INVALID_HANDLE_VALUE || g_log_file == NULL) { |
338 log_file = NULL; | 324 // try the current directory |
325 g_log_file = CreateFile(L".\\debug.log", GENERIC_WRITE, | |
326 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | |
327 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | |
328 if (g_log_file == INVALID_HANDLE_VALUE || g_log_file == NULL) { | |
329 g_log_file = NULL; | |
339 return false; | 330 return false; |
340 } | 331 } |
341 } | 332 } |
342 SetFilePointer(log_file, 0, 0, FILE_END); | 333 SetFilePointer(g_log_file, 0, 0, FILE_END); |
343 #elif defined(OS_POSIX) | 334 #elif defined(OS_POSIX) |
344 log_file = fopen(log_file_name->c_str(), "a"); | 335 g_log_file = fopen(g_log_file_name->c_str(), "a"); |
345 if (log_file == NULL) | 336 if (g_log_file == NULL) |
346 return false; | 337 return false; |
347 #endif | 338 #endif |
348 } | 339 } |
349 | 340 |
350 return true; | 341 return true; |
351 } | 342 } |
352 | 343 |
353 } // namespace | 344 } // namespace |
354 | 345 |
346 LoggingSettings::LoggingSettings() | |
347 : logging_dest(LOG_DEFAULT), | |
348 log_file(NULL), | |
349 lock_log(LOCK_LOG_FILE), | |
350 delete_old(APPEND_TO_OLD_LOG_FILE), | |
351 dcheck_state(DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS) {} | |
355 | 352 |
356 bool BaseInitLoggingImpl(const PathChar* new_log_file, | 353 bool BaseInitLoggingImpl(const LoggingSettings& settings) { |
357 LoggingDestination logging_dest, | |
358 LogLockingState lock_log, | |
359 OldFileDeletionState delete_old, | |
360 DcheckState dcheck_state) { | |
361 #if defined(OS_NACL) | 354 #if defined(OS_NACL) |
362 CHECK(logging_dest == LOG_NONE || | 355 // Can log only to the system debug log. |
363 logging_dest == LOG_ONLY_TO_SYSTEM_DEBUG_LOG); | 356 CHECK_EQ(settings.logging_dest & ~LOG_TO_SYSTEM_DEBUG_LOG, 0); |
364 #endif | 357 #endif |
365 g_dcheck_state = dcheck_state; | 358 g_dcheck_state = settings.dcheck_state; |
366 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 359 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
367 // Don't bother initializing g_vlog_info unless we use one of the | 360 // Don't bother initializing g_vlog_info unless we use one of the |
368 // vlog switches. | 361 // vlog switches. |
369 if (command_line->HasSwitch(switches::kV) || | 362 if (command_line->HasSwitch(switches::kV) || |
370 command_line->HasSwitch(switches::kVModule)) { | 363 command_line->HasSwitch(switches::kVModule)) { |
371 // NOTE: If g_vlog_info has already been initialized, it might be in use | 364 // NOTE: If g_vlog_info has already been initialized, it might be in use |
372 // by another thread. Don't delete the old VLogInfo, just create a second | 365 // by another thread. Don't delete the old VLogInfo, just create a second |
373 // one. We keep track of both to avoid memory leak warnings. | 366 // one. We keep track of both to avoid memory leak warnings. |
374 CHECK(!g_vlog_info_prev); | 367 CHECK(!g_vlog_info_prev); |
375 g_vlog_info_prev = g_vlog_info; | 368 g_vlog_info_prev = g_vlog_info; |
376 | 369 |
377 g_vlog_info = | 370 g_vlog_info = |
378 new VlogInfo(command_line->GetSwitchValueASCII(switches::kV), | 371 new VlogInfo(command_line->GetSwitchValueASCII(switches::kV), |
379 command_line->GetSwitchValueASCII(switches::kVModule), | 372 command_line->GetSwitchValueASCII(switches::kVModule), |
380 &min_log_level); | 373 &g_min_log_level); |
381 } | 374 } |
382 | 375 |
383 LoggingLock::Init(lock_log, new_log_file); | 376 LoggingLock::Init(settings.lock_log, settings.log_file); |
384 | 377 |
385 LoggingLock logging_lock; | 378 LoggingLock logging_lock; |
386 | 379 |
387 if (log_file) { | 380 if (g_log_file) { |
388 // calling InitLogging twice or after some log call has already opened the | 381 // calling InitLogging twice or after some log call has already opened the |
389 // default log file will re-initialize to the new options | 382 // default log file will re-initialize to the new options |
390 CloseFile(log_file); | 383 CloseFile(g_log_file); |
391 log_file = NULL; | 384 g_log_file = NULL; |
392 } | 385 } |
393 | 386 |
394 logging_destination = logging_dest; | 387 g_logging_destination = settings.logging_dest; |
395 | 388 |
396 // ignore file options if logging is disabled or only to system | 389 // ignore file options unless logging to file is set. |
397 if (logging_destination == LOG_NONE || | 390 if ((g_logging_destination & LOG_TO_FILE) == 0) |
398 logging_destination == LOG_ONLY_TO_SYSTEM_DEBUG_LOG) | |
399 return true; | 391 return true; |
400 | 392 |
401 if (!log_file_name) | 393 if (!g_log_file_name) |
402 log_file_name = new PathString(); | 394 g_log_file_name = new PathString(); |
403 *log_file_name = new_log_file; | 395 *g_log_file_name = settings.log_file; |
404 if (delete_old == DELETE_OLD_LOG_FILE) | 396 if (settings.delete_old == DELETE_OLD_LOG_FILE) |
405 DeleteFilePath(*log_file_name); | 397 DeleteFilePath(*g_log_file_name); |
406 | 398 |
407 return InitializeLogFileHandle(); | 399 return InitializeLogFileHandle(); |
408 } | 400 } |
409 | 401 |
410 void SetMinLogLevel(int level) { | 402 void SetMinLogLevel(int level) { |
411 min_log_level = std::min(LOG_ERROR_REPORT, level); | 403 g_min_log_level = std::min(LOG_ERROR_REPORT, level); |
412 } | 404 } |
413 | 405 |
414 int GetMinLogLevel() { | 406 int GetMinLogLevel() { |
415 return min_log_level; | 407 return g_min_log_level; |
416 } | 408 } |
417 | 409 |
418 int GetVlogVerbosity() { | 410 int GetVlogVerbosity() { |
419 return std::max(-1, LOG_INFO - GetMinLogLevel()); | 411 return std::max(-1, LOG_INFO - GetMinLogLevel()); |
420 } | 412 } |
421 | 413 |
422 int GetVlogLevelHelper(const char* file, size_t N) { | 414 int GetVlogLevelHelper(const char* file, size_t N) { |
423 DCHECK_GT(N, 0U); | 415 DCHECK_GT(N, 0U); |
424 // Note: g_vlog_info may change on a different thread during startup | 416 // Note: g_vlog_info may change on a different thread during startup |
425 // (but will always be valid or NULL). | 417 // (but will always be valid or NULL). |
426 VlogInfo* vlog_info = g_vlog_info; | 418 VlogInfo* vlog_info = g_vlog_info; |
427 return vlog_info ? | 419 return vlog_info ? |
428 vlog_info->GetVlogLevel(base::StringPiece(file, N - 1)) : | 420 vlog_info->GetVlogLevel(base::StringPiece(file, N - 1)) : |
429 GetVlogVerbosity(); | 421 GetVlogVerbosity(); |
430 } | 422 } |
431 | 423 |
432 void SetLogItems(bool enable_process_id, bool enable_thread_id, | 424 void SetLogItems(bool enable_process_id, bool enable_thread_id, |
433 bool enable_timestamp, bool enable_tickcount) { | 425 bool enable_timestamp, bool enable_tickcount) { |
434 log_process_id = enable_process_id; | 426 g_log_process_id = enable_process_id; |
435 log_thread_id = enable_thread_id; | 427 g_log_thread_id = enable_thread_id; |
436 log_timestamp = enable_timestamp; | 428 g_log_timestamp = enable_timestamp; |
437 log_tickcount = enable_tickcount; | 429 g_log_tickcount = enable_tickcount; |
438 } | 430 } |
439 | 431 |
440 void SetShowErrorDialogs(bool enable_dialogs) { | 432 void SetShowErrorDialogs(bool enable_dialogs) { |
441 show_error_dialogs = enable_dialogs; | 433 g_show_error_dialogs = enable_dialogs; |
442 } | 434 } |
443 | 435 |
444 void SetLogAssertHandler(LogAssertHandlerFunction handler) { | 436 void SetLogAssertHandler(LogAssertHandlerFunction handler) { |
445 log_assert_handler = handler; | 437 g_log_assert_handler = handler; |
446 } | 438 } |
447 | 439 |
448 void SetLogReportHandler(LogReportHandlerFunction handler) { | 440 void SetLogReportHandler(LogReportHandlerFunction handler) { |
449 log_report_handler = handler; | 441 g_log_report_handler = handler; |
450 } | 442 } |
451 | 443 |
452 void SetLogMessageHandler(LogMessageHandlerFunction handler) { | 444 void SetLogMessageHandler(LogMessageHandlerFunction handler) { |
453 log_message_handler = handler; | 445 g_log_message_handler = handler; |
454 } | 446 } |
455 | 447 |
456 LogMessageHandlerFunction GetLogMessageHandler() { | 448 LogMessageHandlerFunction GetLogMessageHandler() { |
457 return log_message_handler; | 449 return g_log_message_handler; |
458 } | 450 } |
459 | 451 |
460 // MSVC doesn't like complex extern templates and DLLs. | 452 // MSVC doesn't like complex extern templates and DLLs. |
461 #if !defined(COMPILER_MSVC) | 453 #if !defined(COMPILER_MSVC) |
462 // Explicit instantiations for commonly used comparisons. | 454 // Explicit instantiations for commonly used comparisons. |
463 template std::string* MakeCheckOpString<int, int>( | 455 template std::string* MakeCheckOpString<int, int>( |
464 const int&, const int&, const char* names); | 456 const int&, const int&, const char* names); |
465 template std::string* MakeCheckOpString<unsigned long, unsigned long>( | 457 template std::string* MakeCheckOpString<unsigned long, unsigned long>( |
466 const unsigned long&, const unsigned long&, const char* names); | 458 const unsigned long&, const unsigned long&, const char* names); |
467 template std::string* MakeCheckOpString<unsigned long, unsigned int>( | 459 template std::string* MakeCheckOpString<unsigned long, unsigned int>( |
468 const unsigned long&, const unsigned int&, const char* names); | 460 const unsigned long&, const unsigned int&, const char* names); |
469 template std::string* MakeCheckOpString<unsigned int, unsigned long>( | 461 template std::string* MakeCheckOpString<unsigned int, unsigned long>( |
470 const unsigned int&, const unsigned long&, const char* names); | 462 const unsigned int&, const unsigned long&, const char* names); |
471 template std::string* MakeCheckOpString<std::string, std::string>( | 463 template std::string* MakeCheckOpString<std::string, std::string>( |
472 const std::string&, const std::string&, const char* name); | 464 const std::string&, const std::string&, const char* name); |
473 #endif | 465 #endif |
474 | 466 |
475 // Displays a message box to the user with the error message in it. | 467 // Displays a message box to the user with the error message in it. |
476 // Used for fatal messages, where we close the app simultaneously. | 468 // Used for fatal messages, where we close the app simultaneously. |
477 // This is for developers only; we don't use this in circumstances | 469 // This is for developers only; we don't use this in circumstances |
478 // (like release builds) where users could see it, since users don't | 470 // (like release builds) where users could see it, since users don't |
479 // understand these messages anyway. | 471 // understand these messages anyway. |
480 void DisplayDebugMessageInDialog(const std::string& str) { | 472 void DisplayDebugMessageInDialog(const std::string& str) { |
481 if (str.empty()) | 473 if (str.empty()) |
482 return; | 474 return; |
483 | 475 |
484 if (!show_error_dialogs) | 476 if (!g_show_error_dialogs) |
485 return; | 477 return; |
486 | 478 |
487 #if defined(OS_WIN) | 479 #if defined(OS_WIN) |
488 // For Windows programs, it's possible that the message loop is | 480 // For Windows programs, it's possible that the message loop is |
489 // messed up on a fatal error, and creating a MessageBox will cause | 481 // messed up on a fatal error, and creating a MessageBox will cause |
490 // that message loop to be run. Instead, we try to spawn another | 482 // that message loop to be run. Instead, we try to spawn another |
491 // process that displays its command line. We look for "Debug | 483 // process that displays its command line. We look for "Debug |
492 // Message.exe" in the same directory as the application. If it | 484 // Message.exe" in the same directory as the application. If it |
493 // exists, we use it, otherwise, we use a regular message box. | 485 // exists, we use it, otherwise, we use a regular message box. |
494 wchar_t prog_name[MAX_PATH]; | 486 wchar_t prog_name[MAX_PATH]; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
571 // Include a stack trace on a fatal. | 563 // Include a stack trace on a fatal. |
572 base::debug::StackTrace trace; | 564 base::debug::StackTrace trace; |
573 stream_ << std::endl; // Newline to separate from log message. | 565 stream_ << std::endl; // Newline to separate from log message. |
574 trace.OutputToStream(&stream_); | 566 trace.OutputToStream(&stream_); |
575 } | 567 } |
576 #endif | 568 #endif |
577 stream_ << std::endl; | 569 stream_ << std::endl; |
578 std::string str_newline(stream_.str()); | 570 std::string str_newline(stream_.str()); |
579 | 571 |
580 // Give any log message handler first dibs on the message. | 572 // Give any log message handler first dibs on the message. |
581 if (log_message_handler && log_message_handler(severity_, file_, line_, | 573 if (g_log_message_handler && |
582 message_start_, str_newline)) { | 574 g_log_message_handler(severity_, file_, line_, |
575 message_start_, str_newline)) { | |
583 // The handler took care of it, no further processing. | 576 // The handler took care of it, no further processing. |
584 return; | 577 return; |
585 } | 578 } |
586 | 579 |
587 if (logging_destination == LOG_ONLY_TO_SYSTEM_DEBUG_LOG || | 580 if ((g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) { |
588 logging_destination == LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) { | |
589 #if defined(OS_WIN) | 581 #if defined(OS_WIN) |
590 OutputDebugStringA(str_newline.c_str()); | 582 OutputDebugStringA(str_newline.c_str()); |
591 #elif defined(OS_ANDROID) | 583 #elif defined(OS_ANDROID) |
592 android_LogPriority priority = | 584 android_LogPriority priority = |
593 (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN; | 585 (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN; |
594 switch (severity_) { | 586 switch (severity_) { |
595 case LOG_INFO: | 587 case LOG_INFO: |
596 priority = ANDROID_LOG_INFO; | 588 priority = ANDROID_LOG_INFO; |
597 break; | 589 break; |
598 case LOG_WARNING: | 590 case LOG_WARNING: |
(...skipping 21 matching lines...) Expand all Loading... | |
620 | 612 |
621 // We can have multiple threads and/or processes, so try to prevent them | 613 // We can have multiple threads and/or processes, so try to prevent them |
622 // from clobbering each other's writes. | 614 // from clobbering each other's writes. |
623 // If the client app did not call InitLogging, and the lock has not | 615 // If the client app did not call InitLogging, and the lock has not |
624 // been created do it now. We do this on demand, but if two threads try | 616 // been created do it now. We do this on demand, but if two threads try |
625 // to do this at the same time, there will be a race condition to create | 617 // to do this at the same time, there will be a race condition to create |
626 // the lock. This is why InitLogging should be called from the main | 618 // the lock. This is why InitLogging should be called from the main |
627 // thread at the beginning of execution. | 619 // thread at the beginning of execution. |
628 LoggingLock::Init(LOCK_LOG_FILE, NULL); | 620 LoggingLock::Init(LOCK_LOG_FILE, NULL); |
629 // write to log file | 621 // write to log file |
630 if (logging_destination != LOG_NONE && | 622 if ((g_logging_destination & LOG_TO_FILE) != 0) { |
631 logging_destination != LOG_ONLY_TO_SYSTEM_DEBUG_LOG) { | |
632 LoggingLock logging_lock; | 623 LoggingLock logging_lock; |
633 if (InitializeLogFileHandle()) { | 624 if (InitializeLogFileHandle()) { |
634 #if defined(OS_WIN) | 625 #if defined(OS_WIN) |
635 SetFilePointer(log_file, 0, 0, SEEK_END); | 626 SetFilePointer(g_log_file, 0, 0, SEEK_END); |
636 DWORD num_written; | 627 DWORD num_written; |
637 WriteFile(log_file, | 628 WriteFile(g_log_file, |
638 static_cast<const void*>(str_newline.c_str()), | 629 static_cast<const void*>(str_newline.c_str()), |
639 static_cast<DWORD>(str_newline.length()), | 630 static_cast<DWORD>(str_newline.length()), |
640 &num_written, | 631 &num_written, |
641 NULL); | 632 NULL); |
642 #else | 633 #else |
643 fprintf(log_file, "%s", str_newline.c_str()); | 634 fprintf(g_log_file, "%s", str_newline.c_str()); |
644 fflush(log_file); | 635 fflush(g_log_file); |
645 #endif | 636 #endif |
646 } | 637 } |
647 } | 638 } |
648 | 639 |
649 if (severity_ == LOG_FATAL) { | 640 if (severity_ == LOG_FATAL) { |
650 // Ensure the first characters of the string are on the stack so they | 641 // Ensure the first characters of the string are on the stack so they |
651 // are contained in minidumps for diagnostic purposes. | 642 // are contained in minidumps for diagnostic purposes. |
652 char str_stack[1024]; | 643 char str_stack[1024]; |
653 str_newline.copy(str_stack, arraysize(str_stack)); | 644 str_newline.copy(str_stack, arraysize(str_stack)); |
654 base::debug::Alias(str_stack); | 645 base::debug::Alias(str_stack); |
655 | 646 |
656 // display a message or break into the debugger on a fatal error | 647 // display a message or break into the debugger on a fatal error |
657 if (base::debug::BeingDebugged()) { | 648 if (base::debug::BeingDebugged()) { |
658 base::debug::BreakDebugger(); | 649 base::debug::BreakDebugger(); |
659 } else { | 650 } else { |
660 if (log_assert_handler) { | 651 if (g_log_assert_handler) { |
661 // make a copy of the string for the handler out of paranoia | 652 // make a copy of the string for the handler out of paranoia |
662 log_assert_handler(std::string(stream_.str())); | 653 g_log_assert_handler(std::string(stream_.str())); |
663 } else { | 654 } else { |
664 // Don't use the string with the newline, get a fresh version to send to | 655 // Don't use the string with the newline, get a fresh version to send to |
665 // the debug message process. We also don't display assertions to the | 656 // the debug message process. We also don't display assertions to the |
666 // user in release mode. The enduser can't do anything with this | 657 // user in release mode. The enduser can't do anything with this |
667 // information, and displaying message boxes when the application is | 658 // information, and displaying message boxes when the application is |
668 // hosed can cause additional problems. | 659 // hosed can cause additional problems. |
669 #ifndef NDEBUG | 660 #ifndef NDEBUG |
670 DisplayDebugMessageInDialog(stream_.str()); | 661 DisplayDebugMessageInDialog(stream_.str()); |
671 #endif | 662 #endif |
672 // Crash the process to generate a dump. | 663 // Crash the process to generate a dump. |
673 base::debug::BreakDebugger(); | 664 base::debug::BreakDebugger(); |
674 } | 665 } |
675 } | 666 } |
676 } else if (severity_ == LOG_ERROR_REPORT) { | 667 } else if (severity_ == LOG_ERROR_REPORT) { |
677 // We are here only if the user runs with --enable-dcheck in release mode. | 668 // We are here only if the user runs with --enable-dcheck in release mode. |
678 if (log_report_handler) { | 669 if (g_log_report_handler) { |
679 log_report_handler(std::string(stream_.str())); | 670 g_log_report_handler(std::string(stream_.str())); |
680 } else { | 671 } else { |
681 DisplayDebugMessageInDialog(stream_.str()); | 672 DisplayDebugMessageInDialog(stream_.str()); |
682 } | 673 } |
683 } | 674 } |
684 } | 675 } |
685 | 676 |
686 // writes the common header info to the stream | 677 // writes the common header info to the stream |
687 void LogMessage::Init(const char* file, int line) { | 678 void LogMessage::Init(const char* file, int line) { |
688 base::StringPiece filename(file); | 679 base::StringPiece filename(file); |
689 size_t last_slash_pos = filename.find_last_of("\\/"); | 680 size_t last_slash_pos = filename.find_last_of("\\/"); |
690 if (last_slash_pos != base::StringPiece::npos) | 681 if (last_slash_pos != base::StringPiece::npos) |
691 filename.remove_prefix(last_slash_pos + 1); | 682 filename.remove_prefix(last_slash_pos + 1); |
692 | 683 |
693 // TODO(darin): It might be nice if the columns were fixed width. | 684 // TODO(darin): It might be nice if the columns were fixed width. |
694 | 685 |
695 stream_ << '['; | 686 stream_ << '['; |
696 if (log_process_id) | 687 if (g_log_process_id) |
697 stream_ << CurrentProcessId() << ':'; | 688 stream_ << CurrentProcessId() << ':'; |
698 if (log_thread_id) | 689 if (g_log_thread_id) |
699 stream_ << base::PlatformThread::CurrentId() << ':'; | 690 stream_ << base::PlatformThread::CurrentId() << ':'; |
700 if (log_timestamp) { | 691 if (g_log_timestamp) { |
701 time_t t = time(NULL); | 692 time_t t = time(NULL); |
702 struct tm local_time = {0}; | 693 struct tm local_time = {0}; |
703 #if _MSC_VER >= 1400 | 694 #if _MSC_VER >= 1400 |
704 localtime_s(&local_time, &t); | 695 localtime_s(&local_time, &t); |
705 #else | 696 #else |
706 localtime_r(&t, &local_time); | 697 localtime_r(&t, &local_time); |
707 #endif | 698 #endif |
708 struct tm* tm_time = &local_time; | 699 struct tm* tm_time = &local_time; |
709 stream_ << std::setfill('0') | 700 stream_ << std::setfill('0') |
710 << std::setw(2) << 1 + tm_time->tm_mon | 701 << std::setw(2) << 1 + tm_time->tm_mon |
711 << std::setw(2) << tm_time->tm_mday | 702 << std::setw(2) << tm_time->tm_mday |
712 << '/' | 703 << '/' |
713 << std::setw(2) << tm_time->tm_hour | 704 << std::setw(2) << tm_time->tm_hour |
714 << std::setw(2) << tm_time->tm_min | 705 << std::setw(2) << tm_time->tm_min |
715 << std::setw(2) << tm_time->tm_sec | 706 << std::setw(2) << tm_time->tm_sec |
716 << ':'; | 707 << ':'; |
717 } | 708 } |
718 if (log_tickcount) | 709 if (g_log_tickcount) |
719 stream_ << TickCount() << ':'; | 710 stream_ << TickCount() << ':'; |
720 if (severity_ >= 0) | 711 if (severity_ >= 0) |
721 stream_ << log_severity_names[severity_]; | 712 stream_ << kLogSeverityNames[severity_]; |
722 else | 713 else |
723 stream_ << "VERBOSE" << -severity_; | 714 stream_ << "VERBOSE" << -severity_; |
724 | 715 |
725 stream_ << ":" << filename << "(" << line << ")] "; | 716 stream_ << ":" << filename << "(" << line << ")] "; |
726 | 717 |
727 message_start_ = stream_.tellp(); | 718 message_start_ = stream_.tellp(); |
728 } | 719 } |
729 | 720 |
730 #if defined(OS_WIN) | 721 #if defined(OS_WIN) |
731 // This has already been defined in the header, but defining it again as DWORD | 722 // This has already been defined in the header, but defining it again as DWORD |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
815 } | 806 } |
816 | 807 |
817 ErrnoLogMessage::~ErrnoLogMessage() { | 808 ErrnoLogMessage::~ErrnoLogMessage() { |
818 stream() << ": " << safe_strerror(err_); | 809 stream() << ": " << safe_strerror(err_); |
819 } | 810 } |
820 #endif // OS_WIN | 811 #endif // OS_WIN |
821 | 812 |
822 void CloseLogFile() { | 813 void CloseLogFile() { |
823 LoggingLock logging_lock; | 814 LoggingLock logging_lock; |
824 | 815 |
825 if (!log_file) | 816 if (!g_log_file) |
826 return; | 817 return; |
827 | 818 |
828 CloseFile(log_file); | 819 CloseFile(g_log_file); |
829 log_file = NULL; | 820 g_log_file = NULL; |
830 } | 821 } |
831 | 822 |
832 void RawLog(int level, const char* message) { | 823 void RawLog(int level, const char* message) { |
833 if (level >= min_log_level) { | 824 if (level >= g_min_log_level) { |
834 size_t bytes_written = 0; | 825 size_t bytes_written = 0; |
835 const size_t message_len = strlen(message); | 826 const size_t message_len = strlen(message); |
836 int rv; | 827 int rv; |
837 while (bytes_written < message_len) { | 828 while (bytes_written < message_len) { |
838 rv = HANDLE_EINTR( | 829 rv = HANDLE_EINTR( |
839 write(STDERR_FILENO, message + bytes_written, | 830 write(STDERR_FILENO, message + bytes_written, |
840 message_len - bytes_written)); | 831 message_len - bytes_written)); |
841 if (rv < 0) { | 832 if (rv < 0) { |
842 // Give up, nothing we can do now. | 833 // Give up, nothing we can do now. |
843 break; | 834 break; |
(...skipping 14 matching lines...) Expand all Loading... | |
858 | 849 |
859 if (level == LOG_FATAL) | 850 if (level == LOG_FATAL) |
860 base::debug::BreakDebugger(); | 851 base::debug::BreakDebugger(); |
861 } | 852 } |
862 | 853 |
863 // This was defined at the beginning of this file. | 854 // This was defined at the beginning of this file. |
864 #undef write | 855 #undef write |
865 | 856 |
866 #if defined(OS_WIN) | 857 #if defined(OS_WIN) |
867 std::wstring GetLogFileFullPath() { | 858 std::wstring GetLogFileFullPath() { |
868 if (log_file_name) | 859 if (g_log_file_name) |
869 return *log_file_name; | 860 return *g_log_file_name; |
870 return std::wstring(); | 861 return std::wstring(); |
871 } | 862 } |
872 #endif | 863 #endif |
873 | 864 |
874 } // namespace logging | 865 } // namespace logging |
875 | 866 |
876 std::ostream& operator<<(std::ostream& out, const wchar_t* wstr) { | 867 std::ostream& operator<<(std::ostream& out, const wchar_t* wstr) { |
877 return out << WideToUTF8(std::wstring(wstr)); | 868 return out << WideToUTF8(std::wstring(wstr)); |
878 } | 869 } |
OLD | NEW |