bool WaitForDebugger(int wait_seconds, bool silent) { for(int i=0; i<wait_seconds*10; ++i) { if(BeingDebugged()) { if(!silent) { BreakDebugger(); } return true; } PlatformThread::Sleep(100); } return false; }
LogMessage::~LogMessage() { stream_ << std::endl; std::string str_newline(stream_.str()); // Give any log message handler first dibs on the message. if (log_message_handler && log_message_handler(severity_, file_, line_, message_start_, str_newline)) { // The handler took care of it, no further processing. return; } if ((logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) { OutputDebugStringA(str_newline.c_str()); fwrite(str_newline.data(), str_newline.size(), 1, stderr); fflush(stderr); } else if (severity_ >= kAlwaysPrintErrorLevel) { fwrite(str_newline.data(), str_newline.size(), 1, stderr); fflush(stderr); } if ((logging_destination & LOG_TO_FILE) != 0) { LoggingLock::Init(LOCK_LOG_FILE, NULL); LoggingLock logging_lock; if (InitializeLogFileHandle()) { SetFilePointer(log_file, 0, 0, SEEK_END); DWORD num_written; WriteFile(log_file, static_cast<const void*>(str_newline.c_str()), static_cast<DWORD>(str_newline.length()), &num_written, NULL); } } if (severity_ == LOG_FATAL) { // Ensure the first characters of the string are on the stack so they // are contained in minidumps for diagnostic purposes. char str_stack[1024]; str_newline.copy(str_stack, arraysize(str_stack)); // base::debug::Alias(str_stack); if (log_assert_handler) { log_assert_handler(std::string(stream_.str())); } else { // Don't use the string with the newline, get a fresh version to send to // the debug message process. We also don't display assertions to the // user in release mode. The enduser can't do anything with this // information, and displaying message boxes when the application is // hosed can cause additional problems. #ifndef NDEBUG // DisplayDebugMessageInDialog(stream_.str()); #endif // Crash the process to generate a dump. BreakDebugger(); } } }