summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhuanr@chromium.org <huanr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-12 01:19:05 +0000
committerhuanr@chromium.org <huanr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-12 01:19:05 +0000
commitfb62a5370cdd2626eae72bb8ba883287b28e830c (patch)
treee85fe192ebddb13670a81967905b5e4964549233
parentbd580a2503917df061b20b1948297650344b931f (diff)
downloadchromium_src-fb62a5370cdd2626eae72bb8ba883287b28e830c.zip
chromium_src-fb62a5370cdd2626eae72bb8ba883287b28e830c.tar.gz
chromium_src-fb62a5370cdd2626eae72bb8ba883287b28e830c.tar.bz2
Change the behavior of --enable-dcheck in release
build from crashing to logging the failure and continuing. In addition, - In interactive mode, we will display a message box so the user can either click OK and continue or attach a debugger. - If Chrome is running in test environment, it has the option to overide the default behavior and suppress the error dialog. To support this, a new severity level ERROR_REPORT is added. In addition, DFATAL is now mapped to ERROR_REPORT instead of ERROR. The only usage of DFATAL is in ssl_client_socket_nss.cc. Add wtc for code review. Review URL: http://codereview.chromium.org/21216 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9633 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/logging.cc25
-rw-r--r--base/logging.h46
2 files changed, 56 insertions, 15 deletions
diff --git a/base/logging.cc b/base/logging.cc
index cc9c7db..4daefcd 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -46,7 +46,7 @@ namespace logging {
bool g_enable_dcheck = false;
const char* const log_severity_names[LOG_NUM_SEVERITIES] = {
- "INFO", "WARNING", "ERROR", "FATAL" };
+ "INFO", "WARNING", "ERROR", "ERROR_REPORT", "FATAL" };
int min_log_level = 0;
LogLockingState lock_log_file = LOCK_LOG_FILE;
@@ -89,8 +89,11 @@ bool log_timestamp = true;
bool log_tickcount = false;
// An assert handler override specified by the client to be called instead of
-// the debug message dialog.
+// the debug message dialog and process termination.
LogAssertHandlerFunction log_assert_handler = NULL;
+// An report handler override specified by the client to be called instead of
+// the debug message dialog.
+LogReportHandlerFunction log_report_handler = NULL;
// The lock is used if log file locking is false. It helps us avoid problems
// with multiple threads writing to the log file at the same time. Use
@@ -291,6 +294,10 @@ void SetLogAssertHandler(LogAssertHandlerFunction handler) {
log_assert_handler = handler;
}
+void SetLogReportHandler(LogReportHandlerFunction handler) {
+ log_report_handler = handler;
+}
+
// Displays a message box to the user with the error message in it. For
// Windows programs, it's possible that the message loop is messed up on
// a fatal error, and creating a MessageBox will cause that message loop
@@ -348,6 +355,13 @@ LogMessage::LogMessage(const char* file, int line, const CheckOpString& result)
stream_ << "Check failed: " << (*result.str_);
}
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
+ const CheckOpString& result)
+ : severity_(severity) {
+ Init(file, line);
+ stream_ << "Check failed: " << (*result.str_);
+}
+
LogMessage::LogMessage(const char* file, int line)
: severity_(LOG_INFO) {
Init(file, line);
@@ -511,6 +525,13 @@ LogMessage::~LogMessage() {
// dump, but until then, do not invoke the Apple crash reporter.
}
}
+ } else if (severity_ == LOG_ERROR_REPORT) {
+ // We are here only if the user runs with --enable-dcheck in release mode.
+ if (log_report_handler) {
+ log_report_handler(std::string(stream_.str()));
+ } else {
+ DisplayDebugMessage(stream_.str());
+ }
}
}
diff --git a/base/logging.h b/base/logging.h
index 4fd7641..baedb8b 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -77,13 +77,18 @@
// We also override the standard 'assert' to use 'DLOG_ASSERT'.
//
// The supported severity levels for macros that allow you to specify one
-// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL.
-//
-// There is also the special severity of DFATAL, which logs FATAL in
-// debug mode, ERROR in normal mode.
+// are (in increasing order of severity) INFO, WARNING, ERROR, ERROR_REPORT,
+// and FATAL.
//
// Very important: logging a message at the FATAL severity level causes
// the program to terminate (after the message is logged).
+//
+// Note the special severity of ERROR_REPORT only available/relevant in normal
+// mode, which displays error dialog without terminating the program. There is
+// no error dialog for severity ERROR or below in normal mode.
+//
+// There is also the special severity of DFATAL, which logs FATAL in
+// debug mode, ERROR_REPORT in normal mode.
namespace logging {
@@ -151,22 +156,29 @@ void SetLogItems(bool enable_process_id, bool enable_thread_id,
bool enable_timestamp, bool enable_tickcount);
// Sets the Log Assert Handler that will be used to notify of check failures.
-// The default handler shows a dialog box, however clients can use this
-// function to override with their own handling (e.g. a silent one for Unit
-// Tests)
+// The default handler shows a dialog box and then terminate the process,
+// however clients can use this function to override with their own handling
+// (e.g. a silent one for Unit Tests)
typedef void (*LogAssertHandlerFunction)(const std::string& str);
void SetLogAssertHandler(LogAssertHandlerFunction handler);
+// Sets the Log Report Handler that will be used to notify of check failures
+// in non-debug mode. The default handler shows a dialog box and continues
+// the execution, however clients can use this function to override with their
+// own handling.
+typedef void (*LogReportHandlerFunction)(const std::string& str);
+void SetLogReportHandler(LogReportHandlerFunction handler);
typedef int LogSeverity;
const LogSeverity LOG_INFO = 0;
const LogSeverity LOG_WARNING = 1;
const LogSeverity LOG_ERROR = 2;
-const LogSeverity LOG_FATAL = 3;
-const LogSeverity LOG_NUM_SEVERITIES = 4;
+const LogSeverity LOG_ERROR_REPORT = 3;
+const LogSeverity LOG_FATAL = 4;
+const LogSeverity LOG_NUM_SEVERITIES = 5;
-// LOG_DFATAL_LEVEL is LOG_FATAL in debug mode, ERROR in normal mode
+// LOG_DFATAL_LEVEL is LOG_FATAL in debug mode, ERROR_REPORT in normal mode
#ifdef NDEBUG
-const LogSeverity LOG_DFATAL_LEVEL = LOG_ERROR;
+const LogSeverity LOG_DFATAL_LEVEL = LOG_ERROR_REPORT;
#else
const LogSeverity LOG_DFATAL_LEVEL = LOG_FATAL;
#endif
@@ -180,6 +192,8 @@ const LogSeverity LOG_DFATAL_LEVEL = LOG_FATAL;
logging::LogMessage(__FILE__, __LINE__, logging::LOG_WARNING)
#define COMPACT_GOOGLE_LOG_ERROR \
logging::LogMessage(__FILE__, __LINE__, logging::LOG_ERROR)
+#define COMPACT_GOOGLE_LOG_ERROR_REPORT \
+ logging::LogMessage(__FILE__, __LINE__, logging::LOG_ERROR_REPORT)
#define COMPACT_GOOGLE_LOG_FATAL \
logging::LogMessage(__FILE__, __LINE__, logging::LOG_FATAL)
#define COMPACT_GOOGLE_LOG_DFATAL \
@@ -395,7 +409,7 @@ enum { DEBUG_MODE = 0 };
extern bool g_enable_dcheck;
#define DCHECK(condition) \
!logging::g_enable_dcheck ? void (0) : \
- LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". "
+ LOG_IF(ERROR_REPORT, !(condition)) << "Check failed: " #condition ". "
// Helper macro for binary operators.
// Don't use this macro directly in your code, use DCHECK_EQ et al below.
@@ -403,7 +417,8 @@ extern bool g_enable_dcheck;
if (logging::g_enable_dcheck) \
if (logging::CheckOpString _result = \
logging::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \
- logging::LogMessage(__FILE__, __LINE__, _result).stream()
+ logging::LogMessage(__FILE__, __LINE__, logging::LOG_ERROR_REPORT, \
+ _result).stream()
#define DCHECK_STREQ(str1, str2) \
while (false) NDEBUG_EAT_STREAM_PARAMETERS
@@ -508,6 +523,11 @@ class LogMessage {
// Implied severity = LOG_FATAL
LogMessage(const char* file, int line, const CheckOpString& result);
+ // A special constructor used for check failures, with the option to
+ // specify severity.
+ LogMessage(const char* file, int line, LogSeverity severity,
+ const CheckOpString& result);
+
~LogMessage();
std::ostream& stream() { return stream_; }