Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/logging.h"
      6 
      7 #if defined(OS_WIN)
      8 #include <io.h>
      9 #include <windows.h>
     10 typedef HANDLE FileHandle;
     11 typedef HANDLE MutexHandle;
     12 // Windows warns on using write().  It prefers _write().
     13 #define write(fd, buf, count) _write(fd, buf, static_cast<unsigned int>(count))
     14 // Windows doesn't define STDERR_FILENO.  Define it here.
     15 #define STDERR_FILENO 2
     16 #elif defined(OS_MACOSX)
     17 #include <CoreFoundation/CoreFoundation.h>
     18 #include <mach/mach.h>
     19 #include <mach/mach_time.h>
     20 #include <mach-o/dyld.h>
     21 #elif defined(OS_POSIX)
     22 #include <sys/syscall.h>
     23 #include <time.h>
     24 #endif
     25 
     26 #if defined(OS_POSIX)
     27 #include <errno.h>
     28 #include <stdlib.h>
     29 #include <stdio.h>
     30 #include <string.h>
     31 #include <unistd.h>
     32 #define MAX_PATH PATH_MAX
     33 typedef FILE* FileHandle;
     34 typedef pthread_mutex_t* MutexHandle;
     35 #endif
     36 
     37 #include <ctime>
     38 #include <iomanip>
     39 #include <cstring>
     40 #include <algorithm>
     41 
     42 #include "base/base_switches.h"
     43 #include "base/command_line.h"
     44 #include "base/debug_util.h"
     45 #include "base/eintr_wrapper.h"
     46 #include "base/lock_impl.h"
     47 #if defined(OS_POSIX)
     48 #include "base/safe_strerror_posix.h"
     49 #endif
     50 #include "base/string_piece.h"
     51 #include "base/string_util.h"
     52 #include "base/utf_string_conversions.h"
     53 
     54 namespace logging {
     55 
     56 bool g_enable_dcheck = false;
     57 
     58 const char* const log_severity_names[LOG_NUM_SEVERITIES] = {
     59   "INFO", "WARNING", "ERROR", "ERROR_REPORT", "FATAL" };
     60 
     61 int min_log_level = 0;
     62 LogLockingState lock_log_file = LOCK_LOG_FILE;
     63 
     64 // The default set here for logging_destination will only be used if
     65 // InitLogging is not called.  On Windows, use a file next to the exe;
     66 // on POSIX platforms, where it may not even be possible to locate the
     67 // executable on disk, use stderr.
     68 #if defined(OS_WIN)
     69 LoggingDestination logging_destination = LOG_ONLY_TO_FILE;
     70 #elif defined(OS_POSIX)
     71 LoggingDestination logging_destination = LOG_ONLY_TO_SYSTEM_DEBUG_LOG;
     72 #endif
     73 
     74 const int kMaxFilteredLogLevel = LOG_WARNING;
     75 std::string* log_filter_prefix;
     76 
     77 // For LOG_ERROR and above, always print to stderr.
     78 const int kAlwaysPrintErrorLevel = LOG_ERROR;
     79 
     80 // Which log file to use? This is initialized by InitLogging or
     81 // will be lazily initialized to the default value when it is
     82 // first needed.
     83 #if defined(OS_WIN)
     84 typedef wchar_t PathChar;
     85 typedef std::wstring PathString;
     86 #else
     87 typedef char PathChar;
     88 typedef std::string PathString;
     89 #endif
     90 PathString* log_file_name = NULL;
     91 
     92 // this file is lazily opened and the handle may be NULL
     93 FileHandle log_file = NULL;
     94 
     95 // what should be prepended to each message?
     96 bool log_process_id = false;
     97 bool log_thread_id = false;
     98 bool log_timestamp = true;
     99 bool log_tickcount = false;
    100 
    101 // An assert handler override specified by the client to be called instead of
    102 // the debug message dialog and process termination.
    103 LogAssertHandlerFunction log_assert_handler = NULL;
    104 // An report handler override specified by the client to be called instead of
    105 // the debug message dialog.
    106 LogReportHandlerFunction log_report_handler = NULL;
    107 // A log message handler that gets notified of every log message we process.
    108 LogMessageHandlerFunction log_message_handler = NULL;
    109 
    110 // The lock is used if log file locking is false. It helps us avoid problems
    111 // with multiple threads writing to the log file at the same time.  Use
    112 // LockImpl directly instead of using Lock, because Lock makes logging calls.
    113 static LockImpl* log_lock = NULL;
    114 
    115 // When we don't use a lock, we are using a global mutex. We need to do this
    116 // because LockFileEx is not thread safe.
    117 #if defined(OS_WIN)
    118 MutexHandle log_mutex = NULL;
    119 #elif defined(OS_POSIX)
    120 pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
    121 #endif
    122 
    123 // Helper functions to wrap platform differences.
    124 
    125 int32 CurrentProcessId() {
    126 #if defined(OS_WIN)
    127   return GetCurrentProcessId();
    128 #elif defined(OS_POSIX)
    129   return getpid();
    130 #endif
    131 }
    132 
    133 int32 CurrentThreadId() {
    134 #if defined(OS_WIN)
    135   return GetCurrentThreadId();
    136 #elif defined(OS_MACOSX)
    137   return mach_thread_self();
    138 #elif defined(OS_LINUX)
    139   return syscall(__NR_gettid);
    140 #elif defined(OS_FREEBSD)
    141   // TODO(BSD): find a better thread ID
    142   return reinterpret_cast<int64>(pthread_self());
    143 #endif
    144 }
    145 
    146 uint64 TickCount() {
    147 #if defined(OS_WIN)
    148   return GetTickCount();
    149 #elif defined(OS_MACOSX)
    150   return mach_absolute_time();
    151 #elif defined(OS_POSIX)
    152   struct timespec ts;
    153   clock_gettime(CLOCK_MONOTONIC, &ts);
    154 
    155   uint64 absolute_micro =
    156     static_cast<int64>(ts.tv_sec) * 1000000 +
    157     static_cast<int64>(ts.tv_nsec) / 1000;
    158 
    159   return absolute_micro;
    160 #endif
    161 }
    162 
    163 void CloseFile(FileHandle log) {
    164 #if defined(OS_WIN)
    165   CloseHandle(log);
    166 #else
    167   fclose(log);
    168 #endif
    169 }
    170 
    171 void DeleteFilePath(const PathString& log_name) {
    172 #if defined(OS_WIN)
    173   DeleteFile(log_name.c_str());
    174 #else
    175   unlink(log_name.c_str());
    176 #endif
    177 }
    178 
    179 // Called by logging functions to ensure that debug_file is initialized
    180 // and can be used for writing. Returns false if the file could not be
    181 // initialized. debug_file will be NULL in this case.
    182 bool InitializeLogFileHandle() {
    183   if (log_file)
    184     return true;
    185 
    186   if (!log_file_name) {
    187     // Nobody has called InitLogging to specify a debug log file, so here we
    188     // initialize the log file name to a default.
    189 #if defined(OS_WIN)
    190     // On Windows we use the same path as the exe.
    191     wchar_t module_name[MAX_PATH];
    192     GetModuleFileName(NULL, module_name, MAX_PATH);
    193     log_file_name = new std::wstring(module_name);
    194     std::wstring::size_type last_backslash =
    195         log_file_name->rfind('\\', log_file_name->size());
    196     if (last_backslash != std::wstring::npos)
    197       log_file_name->erase(last_backslash + 1);
    198     *log_file_name += L"debug.log";
    199 #elif defined(OS_POSIX)
    200     // On other platforms we just use the current directory.
    201     log_file_name = new std::string("debug.log");
    202 #endif
    203   }
    204 
    205   if (logging_destination == LOG_ONLY_TO_FILE ||
    206       logging_destination == LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) {
    207 #if defined(OS_WIN)
    208     log_file = CreateFile(log_file_name->c_str(), GENERIC_WRITE,
    209                           FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    210                           OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    211     if (log_file == INVALID_HANDLE_VALUE || log_file == NULL) {
    212       // try the current directory
    213       log_file = CreateFile(L".\\debug.log", GENERIC_WRITE,
    214                             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    215                             OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    216       if (log_file == INVALID_HANDLE_VALUE || log_file == NULL) {
    217         log_file = NULL;
    218         return false;
    219       }
    220     }
    221     SetFilePointer(log_file, 0, 0, FILE_END);
    222 #elif defined(OS_POSIX)
    223     log_file = fopen(log_file_name->c_str(), "a");
    224     if (log_file == NULL)
    225       return false;
    226 #endif
    227   }
    228 
    229   return true;
    230 }
    231 
    232 #if defined(OS_POSIX) && !defined(OS_MACOSX)
    233 int GetLoggingFileDescriptor() {
    234   // No locking needed, since this is only called by the zygote server,
    235   // which is single-threaded.
    236   if (log_file)
    237     return fileno(log_file);
    238   return -1;
    239 }
    240 #endif
    241 
    242 void InitLogMutex() {
    243 #if defined(OS_WIN)
    244   if (!log_mutex) {
    245     // \ is not a legal character in mutex names so we replace \ with /
    246     std::wstring safe_name(*log_file_name);
    247     std::replace(safe_name.begin(), safe_name.end(), '\\', '/');
    248     std::wstring t(L"Global\\");
    249     t.append(safe_name);
    250     log_mutex = ::CreateMutex(NULL, FALSE, t.c_str());
    251   }
    252 #elif defined(OS_POSIX)
    253   // statically initialized
    254 #endif
    255 }
    256 
    257 void InitLogging(const PathChar* new_log_file, LoggingDestination logging_dest,
    258                  LogLockingState lock_log, OldFileDeletionState delete_old) {
    259   g_enable_dcheck =
    260       CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableDCHECK);
    261 
    262   if (log_file) {
    263     // calling InitLogging twice or after some log call has already opened the
    264     // default log file will re-initialize to the new options
    265     CloseFile(log_file);
    266     log_file = NULL;
    267   }
    268 
    269   lock_log_file = lock_log;
    270   logging_destination = logging_dest;
    271 
    272   // ignore file options if logging is disabled or only to system
    273   if (logging_destination == LOG_NONE ||
    274       logging_destination == LOG_ONLY_TO_SYSTEM_DEBUG_LOG)
    275     return;
    276 
    277   if (!log_file_name)
    278     log_file_name = new PathString();
    279   *log_file_name = new_log_file;
    280   if (delete_old == DELETE_OLD_LOG_FILE)
    281     DeleteFilePath(*log_file_name);
    282 
    283   if (lock_log_file == LOCK_LOG_FILE) {
    284     InitLogMutex();
    285   } else if (!log_lock) {
    286     log_lock = new LockImpl();
    287   }
    288 
    289   InitializeLogFileHandle();
    290 }
    291 
    292 void SetMinLogLevel(int level) {
    293   min_log_level = level;
    294 }
    295 
    296 int GetMinLogLevel() {
    297   return min_log_level;
    298 }
    299 
    300 void SetLogFilterPrefix(const char* filter)  {
    301   if (log_filter_prefix) {
    302     delete log_filter_prefix;
    303     log_filter_prefix = NULL;
    304   }
    305 
    306   if (filter)
    307     log_filter_prefix = new std::string(filter);
    308 }
    309 
    310 void SetLogItems(bool enable_process_id, bool enable_thread_id,
    311                  bool enable_timestamp, bool enable_tickcount) {
    312   log_process_id = enable_process_id;
    313   log_thread_id = enable_thread_id;
    314   log_timestamp = enable_timestamp;
    315   log_tickcount = enable_tickcount;
    316 }
    317 
    318 void SetLogAssertHandler(LogAssertHandlerFunction handler) {
    319   log_assert_handler = handler;
    320 }
    321 
    322 void SetLogReportHandler(LogReportHandlerFunction handler) {
    323   log_report_handler = handler;
    324 }
    325 
    326 void SetLogMessageHandler(LogMessageHandlerFunction handler) {
    327   log_message_handler = handler;
    328 }
    329 
    330 
    331 // Displays a message box to the user with the error message in it. For
    332 // Windows programs, it's possible that the message loop is messed up on
    333 // a fatal error, and creating a MessageBox will cause that message loop
    334 // to be run. Instead, we try to spawn another process that displays its
    335 // command line. We look for "Debug Message.exe" in the same directory as
    336 // the application. If it exists, we use it, otherwise, we use a regular
    337 // message box.
    338 void DisplayDebugMessage(const std::string& str) {
    339   if (str.empty())
    340     return;
    341 
    342 #if defined(OS_WIN)
    343   // look for the debug dialog program next to our application
    344   wchar_t prog_name[MAX_PATH];
    345   GetModuleFileNameW(NULL, prog_name, MAX_PATH);
    346   wchar_t* backslash = wcsrchr(prog_name, '\\');
    347   if (backslash)
    348     backslash[1] = 0;
    349   wcscat_s(prog_name, MAX_PATH, L"debug_message.exe");
    350 
    351   std::wstring cmdline = UTF8ToWide(str);
    352   if (cmdline.empty())
    353     return;
    354 
    355   STARTUPINFO startup_info;
    356   memset(&startup_info, 0, sizeof(startup_info));
    357   startup_info.cb = sizeof(startup_info);
    358 
    359   PROCESS_INFORMATION process_info;
    360   if (CreateProcessW(prog_name, &cmdline[0], NULL, NULL, false, 0, NULL,
    361                      NULL, &startup_info, &process_info)) {
    362     WaitForSingleObject(process_info.hProcess, INFINITE);
    363     CloseHandle(process_info.hThread);
    364     CloseHandle(process_info.hProcess);
    365   } else {
    366     // debug process broken, let's just do a message box
    367     MessageBoxW(NULL, &cmdline[0], L"Fatal error",
    368                 MB_OK | MB_ICONHAND | MB_TOPMOST);
    369   }
    370 #else
    371   fprintf(stderr, "%s\n", str.c_str());
    372   fflush(stderr);
    373 #endif
    374 }
    375 
    376 #if defined(OS_WIN)
    377 LogMessage::SaveLastError::SaveLastError() : last_error_(::GetLastError()) {
    378 }
    379 
    380 LogMessage::SaveLastError::~SaveLastError() {
    381   ::SetLastError(last_error_);
    382 }
    383 #endif  // defined(OS_WIN)
    384 
    385 LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
    386                        int ctr)
    387     : severity_(severity) {
    388   Init(file, line);
    389 }
    390 
    391 LogMessage::LogMessage(const char* file, int line, const CheckOpString& result)
    392     : severity_(LOG_FATAL) {
    393   Init(file, line);
    394   stream_ << "Check failed: " << (*result.str_);
    395 }
    396 
    397 LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
    398                        const CheckOpString& result)
    399     : severity_(severity) {
    400   Init(file, line);
    401   stream_ << "Check failed: " << (*result.str_);
    402 }
    403 
    404 LogMessage::LogMessage(const char* file, int line)
    405      : severity_(LOG_INFO) {
    406   Init(file, line);
    407 }
    408 
    409 LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
    410     : severity_(severity) {
    411   Init(file, line);
    412 }
    413 
    414 // writes the common header info to the stream
    415 void LogMessage::Init(const char* file, int line) {
    416   // log only the filename
    417   const char* last_slash = strrchr(file, '\\');
    418   if (last_slash)
    419     file = last_slash + 1;
    420 
    421   // TODO(darin): It might be nice if the columns were fixed width.
    422 
    423   stream_ <<  '[';
    424   if (log_process_id)
    425     stream_ << CurrentProcessId() << ':';
    426   if (log_thread_id)
    427     stream_ << CurrentThreadId() << ':';
    428   if (log_timestamp) {
    429     time_t t = time(NULL);
    430     struct tm local_time = {0};
    431 #if _MSC_VER >= 1400
    432     localtime_s(&local_time, &t);
    433 #else
    434     localtime_r(&t, &local_time);
    435 #endif
    436     struct tm* tm_time = &local_time;
    437     stream_ << std::setfill('0')
    438             << std::setw(2) << 1 + tm_time->tm_mon
    439             << std::setw(2) << tm_time->tm_mday
    440             << '/'
    441             << std::setw(2) << tm_time->tm_hour
    442             << std::setw(2) << tm_time->tm_min
    443             << std::setw(2) << tm_time->tm_sec
    444             << ':';
    445   }
    446   if (log_tickcount)
    447     stream_ << TickCount() << ':';
    448   stream_ << log_severity_names[severity_] << ":" << file <<
    449              "(" << line << ")] ";
    450 
    451   message_start_ = stream_.tellp();
    452 }
    453 
    454 LogMessage::~LogMessage() {
    455   // TODO(brettw) modify the macros so that nothing is executed when the log
    456   // level is too high.
    457   if (severity_ < min_log_level)
    458     return;
    459 
    460   std::string str_newline(stream_.str());
    461 #if defined(OS_WIN)
    462   str_newline.append("\r\n");
    463 #else
    464   str_newline.append("\n");
    465 #endif
    466   // Give any log message handler first dibs on the message.
    467   if (log_message_handler && log_message_handler(severity_, str_newline))
    468     return;
    469 
    470   if (log_filter_prefix && severity_ <= kMaxFilteredLogLevel &&
    471       str_newline.compare(message_start_, log_filter_prefix->size(),
    472                           log_filter_prefix->data()) != 0) {
    473     return;
    474   }
    475 
    476   if (logging_destination == LOG_ONLY_TO_SYSTEM_DEBUG_LOG ||
    477       logging_destination == LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) {
    478 #if defined(OS_WIN)
    479     OutputDebugStringA(str_newline.c_str());
    480     if (severity_ >= kAlwaysPrintErrorLevel) {
    481 #else
    482     {
    483 #endif
    484       // TODO(erikkay): this interferes with the layout tests since it grabs
    485       // stderr and stdout and diffs them against known data. Our info and warn
    486       // logs add noise to that.  Ideally, the layout tests would set the log
    487       // level to ignore anything below error.  When that happens, we should
    488       // take this fprintf out of the #else so that Windows users can benefit
    489       // from the output when running tests from the command-line.  In the
    490       // meantime, we leave this in for Mac and Linux, but until this is fixed
    491       // they won't be able to pass any layout tests that have info or warn
    492       // logs.  See http://b/1343647
    493       fprintf(stderr, "%s", str_newline.c_str());
    494       fflush(stderr);
    495     }
    496   } else if (severity_ >= kAlwaysPrintErrorLevel) {
    497     // When we're only outputting to a log file, above a certain log level, we
    498     // should still output to stderr so that we can better detect and diagnose
    499     // problems with unit tests, especially on the buildbots.
    500     fprintf(stderr, "%s", str_newline.c_str());
    501     fflush(stderr);
    502   }
    503 
    504   // write to log file
    505   if (logging_destination != LOG_NONE &&
    506       logging_destination != LOG_ONLY_TO_SYSTEM_DEBUG_LOG &&
    507       InitializeLogFileHandle()) {
    508     // We can have multiple threads and/or processes, so try to prevent them
    509     // from clobbering each other's writes.
    510     if (lock_log_file == LOCK_LOG_FILE) {
    511       // Ensure that the mutex is initialized in case the client app did not
    512       // call InitLogging. This is not thread safe. See below.
    513       InitLogMutex();
    514 
    515 #if defined(OS_WIN)
    516       ::WaitForSingleObject(log_mutex, INFINITE);
    517       // WaitForSingleObject could have returned WAIT_ABANDONED. We don't
    518       // abort the process here. UI tests might be crashy sometimes,
    519       // and aborting the test binary only makes the problem worse.
    520       // We also don't use LOG macros because that might lead to an infinite
    521       // loop. For more info see http://crbug.com/18028.
    522 #elif defined(OS_POSIX)
    523       pthread_mutex_lock(&log_mutex);
    524 #endif
    525     } else {
    526       // use the lock
    527       if (!log_lock) {
    528         // The client app did not call InitLogging, and so the lock has not
    529         // been created. We do this on demand, but if two threads try to do
    530         // this at the same time, there will be a race condition to create
    531         // the lock. This is why InitLogging should be called from the main
    532         // thread at the beginning of execution.
    533         log_lock = new LockImpl();
    534       }
    535       log_lock->Lock();
    536     }
    537 
    538 #if defined(OS_WIN)
    539     SetFilePointer(log_file, 0, 0, SEEK_END);
    540     DWORD num_written;
    541     WriteFile(log_file,
    542               static_cast<const void*>(str_newline.c_str()),
    543               static_cast<DWORD>(str_newline.length()),
    544               &num_written,
    545               NULL);
    546 #else
    547     fprintf(log_file, "%s", str_newline.c_str());
    548     fflush(log_file);
    549 #endif
    550 
    551     if (lock_log_file == LOCK_LOG_FILE) {
    552 #if defined(OS_WIN)
    553       ReleaseMutex(log_mutex);
    554 #elif defined(OS_POSIX)
    555       pthread_mutex_unlock(&log_mutex);
    556 #endif
    557     } else {
    558       log_lock->Unlock();
    559     }
    560   }
    561 
    562   if (severity_ == LOG_FATAL) {
    563     // display a message or break into the debugger on a fatal error
    564     if (DebugUtil::BeingDebugged()) {
    565       DebugUtil::BreakDebugger();
    566     } else {
    567 #ifndef NDEBUG
    568       // Dump a stack trace on a fatal.
    569       StackTrace trace;
    570       stream_ << "\n";  // Newline to separate from log message.
    571       trace.OutputToStream(&stream_);
    572 #endif
    573 
    574       if (log_assert_handler) {
    575         // make a copy of the string for the handler out of paranoia
    576         log_assert_handler(std::string(stream_.str()));
    577       } else {
    578         // Don't use the string with the newline, get a fresh version to send to
    579         // the debug message process. We also don't display assertions to the
    580         // user in release mode. The enduser can't do anything with this
    581         // information, and displaying message boxes when the application is
    582         // hosed can cause additional problems.
    583 #ifndef NDEBUG
    584         DisplayDebugMessage(stream_.str());
    585 #endif
    586         // Crash the process to generate a dump.
    587         DebugUtil::BreakDebugger();
    588       }
    589     }
    590   } else if (severity_ == LOG_ERROR_REPORT) {
    591     // We are here only if the user runs with --enable-dcheck in release mode.
    592     if (log_report_handler) {
    593       log_report_handler(std::string(stream_.str()));
    594     } else {
    595       DisplayDebugMessage(stream_.str());
    596     }
    597   }
    598 }
    599 
    600 #if defined(OS_WIN)
    601 // This has already been defined in the header, but defining it again as DWORD
    602 // ensures that the type used in the header is equivalent to DWORD. If not,
    603 // the redefinition is a compile error.
    604 typedef DWORD SystemErrorCode;
    605 #endif
    606 
    607 SystemErrorCode GetLastSystemErrorCode() {
    608 #if defined(OS_WIN)
    609   return ::GetLastError();
    610 #elif defined(OS_POSIX)
    611   return errno;
    612 #else
    613 #error Not implemented
    614 #endif
    615 }
    616 
    617 #if defined(OS_WIN)
    618 Win32ErrorLogMessage::Win32ErrorLogMessage(const char* file,
    619                                            int line,
    620                                            LogSeverity severity,
    621                                            SystemErrorCode err,
    622                                            const char* module)
    623     : err_(err),
    624       module_(module),
    625       log_message_(file, line, severity) {
    626 }
    627 
    628 Win32ErrorLogMessage::Win32ErrorLogMessage(const char* file,
    629                                            int line,
    630                                            LogSeverity severity,
    631                                            SystemErrorCode err)
    632     : err_(err),
    633       module_(NULL),
    634       log_message_(file, line, severity) {
    635 }
    636 
    637 Win32ErrorLogMessage::~Win32ErrorLogMessage() {
    638   const int error_message_buffer_size = 256;
    639   char msgbuf[error_message_buffer_size];
    640   DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM;
    641   HMODULE hmod;
    642   if (module_) {
    643     hmod = GetModuleHandleA(module_);
    644     if (hmod) {
    645       flags |= FORMAT_MESSAGE_FROM_HMODULE;
    646     } else {
    647       // This makes a nested Win32ErrorLogMessage. It will have module_ of NULL
    648       // so it will not call GetModuleHandle, so recursive errors are
    649       // impossible.
    650       DPLOG(WARNING) << "Couldn't open module " << module_
    651           << " for error message query";
    652     }
    653   } else {
    654     hmod = NULL;
    655   }
    656   DWORD len = FormatMessageA(flags,
    657                              hmod,
    658                              err_,
    659                              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    660                              msgbuf,
    661                              sizeof(msgbuf) / sizeof(msgbuf[0]),
    662                              NULL);
    663   if (len) {
    664     while ((len > 0) &&
    665            isspace(static_cast<unsigned char>(msgbuf[len - 1]))) {
    666       msgbuf[--len] = 0;
    667     }
    668     stream() << ": " << msgbuf;
    669   } else {
    670     stream() << ": Error " << GetLastError() << " while retrieving error "
    671         << err_;
    672   }
    673 }
    674 #elif defined(OS_POSIX)
    675 ErrnoLogMessage::ErrnoLogMessage(const char* file,
    676                                  int line,
    677                                  LogSeverity severity,
    678                                  SystemErrorCode err)
    679     : err_(err),
    680       log_message_(file, line, severity) {
    681 }
    682 
    683 ErrnoLogMessage::~ErrnoLogMessage() {
    684   stream() << ": " << safe_strerror(err_);
    685 }
    686 #endif  // OS_WIN
    687 
    688 void CloseLogFile() {
    689   if (!log_file)
    690     return;
    691 
    692   CloseFile(log_file);
    693   log_file = NULL;
    694 }
    695 
    696 void RawLog(int level, const char* message) {
    697   if (level >= min_log_level) {
    698     size_t bytes_written = 0;
    699     const size_t message_len = strlen(message);
    700     int rv;
    701     while (bytes_written < message_len) {
    702       rv = HANDLE_EINTR(
    703           write(STDERR_FILENO, message + bytes_written,
    704                 message_len - bytes_written));
    705       if (rv < 0) {
    706         // Give up, nothing we can do now.
    707         break;
    708       }
    709       bytes_written += rv;
    710     }
    711 
    712     if (message_len > 0 && message[message_len - 1] != '\n') {
    713       do {
    714         rv = HANDLE_EINTR(write(STDERR_FILENO, "\n", 1));
    715         if (rv < 0) {
    716           // Give up, nothing we can do now.
    717           break;
    718         }
    719       } while (rv != 1);
    720     }
    721   }
    722 
    723   if (level == LOG_FATAL)
    724     DebugUtil::BreakDebugger();
    725 }
    726 
    727 }  // namespace logging
    728 
    729 std::ostream& operator<<(std::ostream& out, const wchar_t* wstr) {
    730   return out << WideToUTF8(std::wstring(wstr));
    731 }
    732