Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: base/logging.cc

Issue 1446363003: Deleted OS_WIN and all Windows specific files from base. (Closed) Base URL: https://github.com/domokit/mojo.git@base_tests
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/logging.h ('k') | base/logging_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_MACOSX)
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 <mach/mach.h> 8 #include <mach/mach.h>
18 #include <mach/mach_time.h> 9 #include <mach/mach_time.h>
19 #include <mach-o/dyld.h> 10 #include <mach-o/dyld.h>
20 #elif defined(OS_POSIX) 11 #elif defined(OS_POSIX)
21 #if defined(OS_NACL) 12 #if defined(OS_NACL)
22 #include <sys/time.h> // timespec doesn't seem to be in <time.h> 13 #include <sys/time.h> // timespec doesn't seem to be in <time.h>
23 #else 14 #else
24 #include <sys/syscall.h> 15 #include <sys/syscall.h>
25 #endif 16 #endif
26 #include <time.h> 17 #include <time.h>
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 int g_min_log_level = 0; 76 int g_min_log_level = 0;
86 77
87 LoggingDestination g_logging_destination = LOG_DEFAULT; 78 LoggingDestination g_logging_destination = LOG_DEFAULT;
88 79
89 // For LOG_ERROR and above, always print to stderr. 80 // For LOG_ERROR and above, always print to stderr.
90 const int kAlwaysPrintErrorLevel = LOG_ERROR; 81 const int kAlwaysPrintErrorLevel = LOG_ERROR;
91 82
92 // Which log file to use? This is initialized by InitLogging or 83 // Which log file to use? This is initialized by InitLogging or
93 // will be lazily initialized to the default value when it is 84 // will be lazily initialized to the default value when it is
94 // first needed. 85 // first needed.
95 #if defined(OS_WIN)
96 typedef std::wstring PathString;
97 #else
98 typedef std::string PathString; 86 typedef std::string PathString;
99 #endif
100 PathString* g_log_file_name = nullptr; 87 PathString* g_log_file_name = nullptr;
101 88
102 // This file is lazily opened and the handle may be nullptr 89 // This file is lazily opened and the handle may be nullptr
103 FileHandle g_log_file = nullptr; 90 FileHandle g_log_file = nullptr;
104 91
105 // What should be prepended to each message? 92 // What should be prepended to each message?
106 bool g_log_process_id = false; 93 bool g_log_process_id = false;
107 bool g_log_thread_id = false; 94 bool g_log_thread_id = false;
108 bool g_log_timestamp = true; 95 bool g_log_timestamp = true;
109 bool g_log_tickcount = false; 96 bool g_log_tickcount = false;
110 97
111 // Should we pop up fatal debug messages in a dialog? 98 // Should we pop up fatal debug messages in a dialog?
112 bool show_error_dialogs = false; 99 bool show_error_dialogs = false;
113 100
114 // An assert handler override specified by the client to be called instead of 101 // An assert handler override specified by the client to be called instead of
115 // the debug message dialog and process termination. 102 // the debug message dialog and process termination.
116 LogAssertHandlerFunction log_assert_handler = nullptr; 103 LogAssertHandlerFunction log_assert_handler = nullptr;
117 // A log message handler that gets notified of every log message we process. 104 // A log message handler that gets notified of every log message we process.
118 LogMessageHandlerFunction log_message_handler = nullptr; 105 LogMessageHandlerFunction log_message_handler = nullptr;
119 106
120 // Helper functions to wrap platform differences. 107 // Helper functions to wrap platform differences.
121 108
122 int32 CurrentProcessId() { 109 int32 CurrentProcessId() {
123 #if defined(OS_WIN)
124 return GetCurrentProcessId();
125 #elif defined(OS_POSIX)
126 return getpid(); 110 return getpid();
127 #endif
128 } 111 }
129 112
130 uint64 TickCount() { 113 uint64 TickCount() {
131 #if defined(OS_WIN) 114 #if defined(OS_MACOSX)
132 return GetTickCount();
133 #elif defined(OS_MACOSX)
134 return mach_absolute_time(); 115 return mach_absolute_time();
135 #elif defined(OS_NACL) 116 #elif defined(OS_NACL)
136 // NaCl sadly does not have _POSIX_TIMERS enabled in sys/features.h 117 // NaCl sadly does not have _POSIX_TIMERS enabled in sys/features.h
137 // So we have to use clock() for now. 118 // So we have to use clock() for now.
138 return clock(); 119 return clock();
139 #elif defined(OS_POSIX) 120 #elif defined(OS_POSIX)
140 struct timespec ts; 121 struct timespec ts;
141 clock_gettime(CLOCK_MONOTONIC, &ts); 122 clock_gettime(CLOCK_MONOTONIC, &ts);
142 123
143 uint64 absolute_micro = 124 uint64 absolute_micro =
144 static_cast<int64>(ts.tv_sec) * 1000000 + 125 static_cast<int64>(ts.tv_sec) * 1000000 +
145 static_cast<int64>(ts.tv_nsec) / 1000; 126 static_cast<int64>(ts.tv_nsec) / 1000;
146 127
147 return absolute_micro; 128 return absolute_micro;
148 #endif 129 #endif
149 } 130 }
150 131
151 void DeleteFilePath(const PathString& log_name) { 132 void DeleteFilePath(const PathString& log_name) {
152 #if defined(OS_WIN) 133 #if defined(OS_NACL)
153 DeleteFile(log_name.c_str());
154 #elif defined(OS_NACL)
155 // Do nothing; unlink() isn't supported on NaCl. 134 // Do nothing; unlink() isn't supported on NaCl.
156 #else 135 #else
157 unlink(log_name.c_str()); 136 unlink(log_name.c_str());
158 #endif 137 #endif
159 } 138 }
160 139
161 PathString GetDefaultLogFile() { 140 PathString GetDefaultLogFile() {
162 #if defined(OS_WIN)
163 // On Windows we use the same path as the exe.
164 wchar_t module_name[MAX_PATH];
165 GetModuleFileName(nullptr, module_name, MAX_PATH);
166
167 PathString log_name = module_name;
168 PathString::size_type last_backslash = log_name.rfind('\\', log_name.size());
169 if (last_backslash != PathString::npos)
170 log_name.erase(last_backslash + 1);
171 log_name += L"debug.log";
172 return log_name;
173 #elif defined(OS_POSIX)
174 // On other platforms we just use the current directory. 141 // On other platforms we just use the current directory.
175 return PathString("debug.log"); 142 return PathString("debug.log");
176 #endif
177 } 143 }
178 144
179 // This class acts as a wrapper for locking the logging files. 145 // This class acts as a wrapper for locking the logging files.
180 // LoggingLock::Init() should be called from the main thread before any logging 146 // LoggingLock::Init() should be called from the main thread before any logging
181 // is done. Then whenever logging, be sure to have a local LoggingLock 147 // is done. Then whenever logging, be sure to have a local LoggingLock
182 // instance on the stack. This will ensure that the lock is unlocked upon 148 // instance on the stack. This will ensure that the lock is unlocked upon
183 // exiting the frame. 149 // exiting the frame.
184 // LoggingLocks can not be nested. 150 // LoggingLocks can not be nested.
185 class LoggingLock { 151 class LoggingLock {
186 public: 152 public:
187 LoggingLock() { 153 LoggingLock() {
188 LockLogging(); 154 LockLogging();
189 } 155 }
190 156
191 ~LoggingLock() { 157 ~LoggingLock() {
192 UnlockLogging(); 158 UnlockLogging();
193 } 159 }
194 160
195 static void Init(LogLockingState lock_log, const PathChar* new_log_file) { 161 static void Init(LogLockingState lock_log, const PathChar* new_log_file) {
196 if (initialized) 162 if (initialized)
197 return; 163 return;
198 lock_log_file = lock_log; 164 lock_log_file = lock_log;
199 if (lock_log_file == LOCK_LOG_FILE) { 165 if (lock_log_file == LOCK_LOG_FILE) {
200 #if defined(OS_WIN)
201 if (!log_mutex) {
202 std::wstring safe_name;
203 if (new_log_file)
204 safe_name = new_log_file;
205 else
206 safe_name = GetDefaultLogFile();
207 // \ is not a legal character in mutex names so we replace \ with /
208 std::replace(safe_name.begin(), safe_name.end(), '\\', '/');
209 std::wstring t(L"Global\\");
210 t.append(safe_name);
211 log_mutex = ::CreateMutex(nullptr, FALSE, t.c_str());
212
213 if (log_mutex == nullptr) {
214 #if DEBUG
215 // Keep the error code for debugging
216 int error = GetLastError(); // NOLINT
217 base::debug::BreakDebugger();
218 #endif
219 // Return nicely without putting initialized to true.
220 return;
221 }
222 }
223 #endif
224 } else { 166 } else {
225 log_lock = new base::internal::LockImpl(); 167 log_lock = new base::internal::LockImpl();
226 } 168 }
227 initialized = true; 169 initialized = true;
228 } 170 }
229 171
230 private: 172 private:
231 static void LockLogging() { 173 static void LockLogging() {
232 if (lock_log_file == LOCK_LOG_FILE) { 174 if (lock_log_file == LOCK_LOG_FILE) {
233 #if defined(OS_WIN) 175 #if defined(OS_POSIX)
234 ::WaitForSingleObject(log_mutex, INFINITE);
235 // WaitForSingleObject could have returned WAIT_ABANDONED. We don't
236 // abort the process here. UI tests might be crashy sometimes,
237 // and aborting the test binary only makes the problem worse.
238 // We also don't use LOG macros because that might lead to an infinite
239 // loop. For more info see http://crbug.com/18028.
240 #elif defined(OS_POSIX)
241 pthread_mutex_lock(&log_mutex); 176 pthread_mutex_lock(&log_mutex);
242 #endif 177 #endif
243 } else { 178 } else {
244 // use the lock 179 // use the lock
245 log_lock->Lock(); 180 log_lock->Lock();
246 } 181 }
247 } 182 }
248 183
249 static void UnlockLogging() { 184 static void UnlockLogging() {
250 if (lock_log_file == LOCK_LOG_FILE) { 185 if (lock_log_file == LOCK_LOG_FILE) {
251 #if defined(OS_WIN) 186 #if defined(OS_POSIX)
252 ReleaseMutex(log_mutex);
253 #elif defined(OS_POSIX)
254 pthread_mutex_unlock(&log_mutex); 187 pthread_mutex_unlock(&log_mutex);
255 #endif 188 #endif
256 } else { 189 } else {
257 log_lock->Unlock(); 190 log_lock->Unlock();
258 } 191 }
259 } 192 }
260 193
261 // The lock is used if log file locking is false. It helps us avoid problems 194 // The lock is used if log file locking is false. It helps us avoid problems
262 // with multiple threads writing to the log file at the same time. Use 195 // with multiple threads writing to the log file at the same time. Use
263 // LockImpl directly instead of using Lock, because Lock makes logging calls. 196 // LockImpl directly instead of using Lock, because Lock makes logging calls.
264 static base::internal::LockImpl* log_lock; 197 static base::internal::LockImpl* log_lock;
265 198
266 // When we don't use a lock, we are using a global mutex. We need to do this 199 // When we don't use a lock, we are using a global mutex. We need to do this
267 // because LockFileEx is not thread safe. 200 // because LockFileEx is not thread safe.
268 #if defined(OS_WIN) 201 #if defined(OS_POSIX)
269 static MutexHandle log_mutex;
270 #elif defined(OS_POSIX)
271 static pthread_mutex_t log_mutex; 202 static pthread_mutex_t log_mutex;
272 #endif 203 #endif
273 204
274 static bool initialized; 205 static bool initialized;
275 static LogLockingState lock_log_file; 206 static LogLockingState lock_log_file;
276 }; 207 };
277 208
278 // static 209 // static
279 bool LoggingLock::initialized = false; 210 bool LoggingLock::initialized = false;
280 // static 211 // static
281 base::internal::LockImpl* LoggingLock::log_lock = nullptr; 212 base::internal::LockImpl* LoggingLock::log_lock = nullptr;
282 // static 213 // static
283 LogLockingState LoggingLock::lock_log_file = LOCK_LOG_FILE; 214 LogLockingState LoggingLock::lock_log_file = LOCK_LOG_FILE;
284 215
285 #if defined(OS_WIN) 216 #if defined(OS_POSIX)
286 // static
287 MutexHandle LoggingLock::log_mutex = nullptr;
288 #elif defined(OS_POSIX)
289 pthread_mutex_t LoggingLock::log_mutex = PTHREAD_MUTEX_INITIALIZER; 217 pthread_mutex_t LoggingLock::log_mutex = PTHREAD_MUTEX_INITIALIZER;
290 #endif 218 #endif
291 219
292 // Called by logging functions to ensure that |g_log_file| is initialized 220 // Called by logging functions to ensure that |g_log_file| is initialized
293 // and can be used for writing. Returns false if the file could not be 221 // and can be used for writing. Returns false if the file could not be
294 // initialized. |g_log_file| will be nullptr in this case. 222 // initialized. |g_log_file| will be nullptr in this case.
295 bool InitializeLogFileHandle() { 223 bool InitializeLogFileHandle() {
296 if (g_log_file) 224 if (g_log_file)
297 return true; 225 return true;
298 226
299 if (!g_log_file_name) { 227 if (!g_log_file_name) {
300 // Nobody has called InitLogging to specify a debug log file, so here we 228 // Nobody has called InitLogging to specify a debug log file, so here we
301 // initialize the log file name to a default. 229 // initialize the log file name to a default.
302 g_log_file_name = new PathString(GetDefaultLogFile()); 230 g_log_file_name = new PathString(GetDefaultLogFile());
303 } 231 }
304 232
305 if ((g_logging_destination & LOG_TO_FILE) != 0) { 233 if ((g_logging_destination & LOG_TO_FILE) != 0) {
306 #if defined(OS_WIN) 234 #if defined(OS_POSIX)
307 g_log_file = CreateFile(g_log_file_name->c_str(), GENERIC_WRITE,
308 FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
309 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
310 if (g_log_file == INVALID_HANDLE_VALUE || g_log_file == nullptr) {
311 // try the current directory
312 g_log_file = CreateFile(L".\\debug.log", GENERIC_WRITE,
313 FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
314 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
315 if (g_log_file == INVALID_HANDLE_VALUE || g_log_file == nullptr) {
316 g_log_file = nullptr;
317 return false;
318 }
319 }
320 SetFilePointer(g_log_file, 0, 0, FILE_END);
321 #elif defined(OS_POSIX)
322 g_log_file = fopen(g_log_file_name->c_str(), "a"); 235 g_log_file = fopen(g_log_file_name->c_str(), "a");
323 if (g_log_file == nullptr) 236 if (g_log_file == nullptr)
324 return false; 237 return false;
325 #endif 238 #endif
326 } 239 }
327 240
328 return true; 241 return true;
329 } 242 }
330 243
331 void CloseFile(FileHandle log) { 244 void CloseFile(FileHandle log) {
332 #if defined(OS_WIN)
333 CloseHandle(log);
334 #else
335 fclose(log); 245 fclose(log);
336 #endif
337 } 246 }
338 247
339 void CloseLogFileUnlocked() { 248 void CloseLogFileUnlocked() {
340 if (!g_log_file) 249 if (!g_log_file)
341 return; 250 return;
342 251
343 CloseFile(g_log_file); 252 CloseFile(g_log_file);
344 g_log_file = nullptr; 253 g_log_file = nullptr;
345 } 254 }
346 255
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 // Used for fatal messages, where we close the app simultaneously. 368 // Used for fatal messages, where we close the app simultaneously.
460 // This is for developers only; we don't use this in circumstances 369 // This is for developers only; we don't use this in circumstances
461 // (like release builds) where users could see it, since users don't 370 // (like release builds) where users could see it, since users don't
462 // understand these messages anyway. 371 // understand these messages anyway.
463 void DisplayDebugMessageInDialog(const std::string& str) { 372 void DisplayDebugMessageInDialog(const std::string& str) {
464 if (str.empty()) 373 if (str.empty())
465 return; 374 return;
466 375
467 if (!show_error_dialogs) 376 if (!show_error_dialogs)
468 return; 377 return;
469
470 #if defined(OS_WIN)
471 // For Windows programs, it's possible that the message loop is
472 // messed up on a fatal error, and creating a MessageBox will cause
473 // that message loop to be run. Instead, we try to spawn another
474 // process that displays its command line. We look for "Debug
475 // Message.exe" in the same directory as the application. If it
476 // exists, we use it, otherwise, we use a regular message box.
477 wchar_t prog_name[MAX_PATH];
478 GetModuleFileNameW(nullptr, prog_name, MAX_PATH);
479 wchar_t* backslash = wcsrchr(prog_name, '\\');
480 if (backslash)
481 backslash[1] = 0;
482 wcscat_s(prog_name, MAX_PATH, L"debug_message.exe");
483
484 std::wstring cmdline = base::UTF8ToWide(str);
485 if (cmdline.empty())
486 return;
487
488 STARTUPINFO startup_info;
489 memset(&startup_info, 0, sizeof(startup_info));
490 startup_info.cb = sizeof(startup_info);
491
492 PROCESS_INFORMATION process_info;
493 if (CreateProcessW(prog_name, &cmdline[0], nullptr, nullptr, false, 0,
494 nullptr, nullptr, &startup_info, &process_info)) {
495 WaitForSingleObject(process_info.hProcess, INFINITE);
496 CloseHandle(process_info.hThread);
497 CloseHandle(process_info.hProcess);
498 } else {
499 // debug process broken, let's just do a message box
500 MessageBoxW(nullptr, &cmdline[0], L"Fatal error",
501 MB_OK | MB_ICONHAND | MB_TOPMOST);
502 }
503 #else
504 // We intentionally don't implement a dialog on other platforms.
505 // You can just look at stderr.
506 #endif // defined(OS_WIN)
507 } 378 }
508 #endif // !defined(NDEBUG) 379 #endif // !defined(NDEBUG)
509 380
510 #if defined(OS_WIN)
511 LogMessage::SaveLastError::SaveLastError() : last_error_(::GetLastError()) {
512 }
513
514 LogMessage::SaveLastError::~SaveLastError() {
515 ::SetLastError(last_error_);
516 }
517 #endif // defined(OS_WIN)
518
519 LogMessage::LogMessage(const char* file, int line, LogSeverity severity) 381 LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
520 : severity_(severity), file_(file), line_(line) { 382 : severity_(severity), file_(file), line_(line) {
521 Init(file, line); 383 Init(file, line);
522 } 384 }
523 385
524 LogMessage::LogMessage(const char* file, int line, std::string* result) 386 LogMessage::LogMessage(const char* file, int line, std::string* result)
525 : severity_(LOG_FATAL), file_(file), line_(line) { 387 : severity_(LOG_FATAL), file_(file), line_(line) {
526 Init(file, line); 388 Init(file, line);
527 stream_ << "Check failed: " << *result; 389 stream_ << "Check failed: " << *result;
528 delete result; 390 delete result;
(...skipping 21 matching lines...) Expand all
550 412
551 // Give any log message handler first dibs on the message. 413 // Give any log message handler first dibs on the message.
552 if (log_message_handler && 414 if (log_message_handler &&
553 log_message_handler(severity_, file_, line_, 415 log_message_handler(severity_, file_, line_,
554 message_start_, str_newline)) { 416 message_start_, str_newline)) {
555 // The handler took care of it, no further processing. 417 // The handler took care of it, no further processing.
556 return; 418 return;
557 } 419 }
558 420
559 if ((g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) { 421 if ((g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) {
560 #if defined(OS_WIN) 422 #if defined(OS_ANDROID)
561 OutputDebugStringA(str_newline.c_str());
562 #elif defined(OS_ANDROID)
563 android_LogPriority priority = 423 android_LogPriority priority =
564 (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN; 424 (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN;
565 switch (severity_) { 425 switch (severity_) {
566 case LOG_INFO: 426 case LOG_INFO:
567 priority = ANDROID_LOG_INFO; 427 priority = ANDROID_LOG_INFO;
568 break; 428 break;
569 case LOG_WARNING: 429 case LOG_WARNING:
570 priority = ANDROID_LOG_WARN; 430 priority = ANDROID_LOG_WARN;
571 break; 431 break;
572 case LOG_ERROR: 432 case LOG_ERROR:
(...skipping 20 matching lines...) Expand all
593 // We can have multiple threads and/or processes, so try to prevent them 453 // We can have multiple threads and/or processes, so try to prevent them
594 // from clobbering each other's writes. 454 // from clobbering each other's writes.
595 // If the client app did not call InitLogging, and the lock has not 455 // If the client app did not call InitLogging, and the lock has not
596 // been created do it now. We do this on demand, but if two threads try 456 // been created do it now. We do this on demand, but if two threads try
597 // to do this at the same time, there will be a race condition to create 457 // to do this at the same time, there will be a race condition to create
598 // the lock. This is why InitLogging should be called from the main 458 // the lock. This is why InitLogging should be called from the main
599 // thread at the beginning of execution. 459 // thread at the beginning of execution.
600 LoggingLock::Init(LOCK_LOG_FILE, nullptr); 460 LoggingLock::Init(LOCK_LOG_FILE, nullptr);
601 LoggingLock logging_lock; 461 LoggingLock logging_lock;
602 if (InitializeLogFileHandle()) { 462 if (InitializeLogFileHandle()) {
603 #if defined(OS_WIN)
604 SetFilePointer(g_log_file, 0, 0, SEEK_END);
605 DWORD num_written;
606 WriteFile(g_log_file,
607 static_cast<const void*>(str_newline.c_str()),
608 static_cast<DWORD>(str_newline.length()),
609 &num_written,
610 nullptr);
611 #else
612 ignore_result(fwrite( 463 ignore_result(fwrite(
613 str_newline.data(), str_newline.size(), 1, g_log_file)); 464 str_newline.data(), str_newline.size(), 1, g_log_file));
614 fflush(g_log_file); 465 fflush(g_log_file);
615 #endif
616 } 466 }
617 } 467 }
618 468
619 if (severity_ == LOG_FATAL) { 469 if (severity_ == LOG_FATAL) {
620 // Ensure the first characters of the string are on the stack so they 470 // Ensure the first characters of the string are on the stack so they
621 // are contained in minidumps for diagnostic purposes. 471 // are contained in minidumps for diagnostic purposes.
622 char str_stack[1024]; 472 char str_stack[1024];
623 str_newline.copy(str_stack, arraysize(str_stack)); 473 str_newline.copy(str_stack, arraysize(str_stack));
624 base::debug::Alias(str_stack); 474 base::debug::Alias(str_stack);
625 475
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 if (severity_ >= 0) 528 if (severity_ >= 0)
679 stream_ << log_severity_name(severity_); 529 stream_ << log_severity_name(severity_);
680 else 530 else
681 stream_ << "VERBOSE" << -severity_; 531 stream_ << "VERBOSE" << -severity_;
682 532
683 stream_ << ":" << filename << "(" << line << ")] "; 533 stream_ << ":" << filename << "(" << line << ")] ";
684 534
685 message_start_ = stream_.str().length(); 535 message_start_ = stream_.str().length();
686 } 536 }
687 537
688 #if defined(OS_WIN)
689 // This has already been defined in the header, but defining it again as DWORD
690 // ensures that the type used in the header is equivalent to DWORD. If not,
691 // the redefinition is a compile error.
692 typedef DWORD SystemErrorCode;
693 #endif
694
695 SystemErrorCode GetLastSystemErrorCode() { 538 SystemErrorCode GetLastSystemErrorCode() {
696 #if defined(OS_WIN) 539 #if defined(OS_POSIX)
697 return ::GetLastError();
698 #elif defined(OS_POSIX)
699 return errno; 540 return errno;
700 #else 541 #else
701 #error Not implemented 542 #error Not implemented
702 #endif 543 #endif
703 } 544 }
704 545
705 #if defined(OS_WIN) 546 #if defined(OS_POSIX)
706 BASE_EXPORT std::string SystemErrorCodeToString(SystemErrorCode error_code) {
707 const int kErrorMessageBufferSize = 256;
708 char msgbuf[kErrorMessageBufferSize];
709 DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
710 DWORD len = FormatMessageA(flags, nullptr, error_code, 0, msgbuf,
711 arraysize(msgbuf), nullptr);
712 if (len) {
713 // Messages returned by system end with line breaks.
714 return base::CollapseWhitespaceASCII(msgbuf, true) +
715 base::StringPrintf(" (0x%X)", error_code);
716 }
717 return base::StringPrintf("Error (0x%X) while retrieving error. (0x%X)",
718 GetLastError(), error_code);
719 }
720 #elif defined(OS_POSIX)
721 BASE_EXPORT std::string SystemErrorCodeToString(SystemErrorCode error_code) { 547 BASE_EXPORT std::string SystemErrorCodeToString(SystemErrorCode error_code) {
722 return base::safe_strerror(error_code); 548 return base::safe_strerror(error_code);
723 } 549 }
724 #else 550 #else
725 #error Not implemented 551 #error Not implemented
726 #endif // defined(OS_WIN) 552 #endif // defined(OS_POSIX)
727 553
728 554 #if defined(OS_POSIX)
729 #if defined(OS_WIN)
730 Win32ErrorLogMessage::Win32ErrorLogMessage(const char* file,
731 int line,
732 LogSeverity severity,
733 SystemErrorCode err)
734 : err_(err),
735 log_message_(file, line, severity) {
736 }
737
738 Win32ErrorLogMessage::~Win32ErrorLogMessage() {
739 stream() << ": " << SystemErrorCodeToString(err_);
740 // We're about to crash (CHECK). Put |err_| on the stack (by placing it in a
741 // field) and use Alias in hopes that it makes it into crash dumps.
742 DWORD last_error = err_;
743 base::debug::Alias(&last_error);
744 }
745 #elif defined(OS_POSIX)
746 ErrnoLogMessage::ErrnoLogMessage(const char* file, 555 ErrnoLogMessage::ErrnoLogMessage(const char* file,
747 int line, 556 int line,
748 LogSeverity severity, 557 LogSeverity severity,
749 SystemErrorCode err) 558 SystemErrorCode err)
750 : err_(err), 559 : err_(err),
751 log_message_(file, line, severity) { 560 log_message_(file, line, severity) {
752 } 561 }
753 562
754 ErrnoLogMessage::~ErrnoLogMessage() { 563 ErrnoLogMessage::~ErrnoLogMessage() {
755 stream() << ": " << SystemErrorCodeToString(err_); 564 stream() << ": " << SystemErrorCodeToString(err_);
756 } 565 }
757 #endif // defined(OS_WIN) 566 #endif // defined(OS_POSIX)
758 567
759 void CloseLogFile() { 568 void CloseLogFile() {
760 LoggingLock logging_lock; 569 LoggingLock logging_lock;
761 CloseLogFileUnlocked(); 570 CloseLogFileUnlocked();
762 } 571 }
763 572
764 void RawLog(int level, const char* message) { 573 void RawLog(int level, const char* message) {
765 if (level >= g_min_log_level) { 574 if (level >= g_min_log_level) {
766 size_t bytes_written = 0; 575 size_t bytes_written = 0;
767 const size_t message_len = strlen(message); 576 const size_t message_len = strlen(message);
(...skipping 20 matching lines...) Expand all
788 } 597 }
789 } 598 }
790 599
791 if (level == LOG_FATAL) 600 if (level == LOG_FATAL)
792 base::debug::BreakDebugger(); 601 base::debug::BreakDebugger();
793 } 602 }
794 603
795 // This was defined at the beginning of this file. 604 // This was defined at the beginning of this file.
796 #undef write 605 #undef write
797 606
798 #if defined(OS_WIN)
799 std::wstring GetLogFileFullPath() {
800 if (g_log_file_name)
801 return *g_log_file_name;
802 return std::wstring();
803 }
804 #endif
805
806 BASE_EXPORT void LogErrorNotReached(const char* file, int line) { 607 BASE_EXPORT void LogErrorNotReached(const char* file, int line) {
807 LogMessage(file, line, LOG_ERROR).stream() 608 LogMessage(file, line, LOG_ERROR).stream()
808 << "NOTREACHED() hit."; 609 << "NOTREACHED() hit.";
809 } 610 }
810 611
811 } // namespace logging 612 } // namespace logging
812 613
813 std::ostream& std::operator<<(std::ostream& out, const wchar_t* wstr) { 614 std::ostream& std::operator<<(std::ostream& out, const wchar_t* wstr) {
814 return out << base::WideToUTF8(wstr); 615 return out << base::WideToUTF8(wstr);
815 } 616 }
OLDNEW
« no previous file with comments | « base/logging.h ('k') | base/logging_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698