• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CurrentProcessId()125 int32 CurrentProcessId() {
126 #if defined(OS_WIN)
127   return GetCurrentProcessId();
128 #elif defined(OS_POSIX)
129   return getpid();
130 #endif
131 }
132 
CurrentThreadId()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 
TickCount()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 
CloseFile(FileHandle log)163 void CloseFile(FileHandle log) {
164 #if defined(OS_WIN)
165   CloseHandle(log);
166 #else
167   fclose(log);
168 #endif
169 }
170 
DeleteFilePath(const PathString & log_name)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.
InitializeLogFileHandle()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)
GetLoggingFileDescriptor()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 
InitLogMutex()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 
InitLogging(const PathChar * new_log_file,LoggingDestination logging_dest,LogLockingState lock_log,OldFileDeletionState delete_old)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 
SetMinLogLevel(int level)292 void SetMinLogLevel(int level) {
293   min_log_level = level;
294 }
295 
GetMinLogLevel()296 int GetMinLogLevel() {
297   return min_log_level;
298 }
299 
SetLogFilterPrefix(const char * filter)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 
SetLogItems(bool enable_process_id,bool enable_thread_id,bool enable_timestamp,bool enable_tickcount)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 
SetLogAssertHandler(LogAssertHandlerFunction handler)318 void SetLogAssertHandler(LogAssertHandlerFunction handler) {
319   log_assert_handler = handler;
320 }
321 
SetLogReportHandler(LogReportHandlerFunction handler)322 void SetLogReportHandler(LogReportHandlerFunction handler) {
323   log_report_handler = handler;
324 }
325 
SetLogMessageHandler(LogMessageHandlerFunction handler)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.
DisplayDebugMessage(const std::string & str)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)
SaveLastError()377 LogMessage::SaveLastError::SaveLastError() : last_error_(::GetLastError()) {
378 }
379 
~SaveLastError()380 LogMessage::SaveLastError::~SaveLastError() {
381   ::SetLastError(last_error_);
382 }
383 #endif  // defined(OS_WIN)
384 
LogMessage(const char * file,int line,LogSeverity severity,int ctr)385 LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
386                        int ctr)
387     : severity_(severity) {
388   Init(file, line);
389 }
390 
LogMessage(const char * file,int line,const CheckOpString & result)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 
LogMessage(const char * file,int line,LogSeverity severity,const CheckOpString & result)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 
LogMessage(const char * file,int line)404 LogMessage::LogMessage(const char* file, int line)
405      : severity_(LOG_INFO) {
406   Init(file, line);
407 }
408 
LogMessage(const char * file,int line,LogSeverity severity)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
Init(const char * file,int line)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 
~LogMessage()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 
operator <<(std::ostream & out,const wchar_t * wstr)729 std::ostream& operator<<(std::ostream& out, const wchar_t* wstr) {
730   return out << WideToUTF8(std::wstring(wstr));
731 }
732