diff options
author | pinkerton@google.com <pinkerton@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-08 13:27:28 +0000 |
---|---|---|
committer | pinkerton@google.com <pinkerton@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-08 13:27:28 +0000 |
commit | f6abebaff2f9cc1b04dfa986c6b4a79cb3c0af5e (patch) | |
tree | b72a9c4e37f875f5c9cf886afabd328d885a2e25 /base/logging.cc | |
parent | 9fa878b4d05f0164b1489aa62821c504dc128d9b (diff) | |
download | chromium_src-f6abebaff2f9cc1b04dfa986c6b4a79cb3c0af5e.zip chromium_src-f6abebaff2f9cc1b04dfa986c6b4a79cb3c0af5e.tar.gz chromium_src-f6abebaff2f9cc1b04dfa986c6b4a79cb3c0af5e.tar.bz2 |
Logging cleanup for mac and linux
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@561 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/logging.cc')
-rw-r--r-- | base/logging.cc | 179 |
1 files changed, 164 insertions, 15 deletions
diff --git a/base/logging.cc b/base/logging.cc index ca9905d..559934b 100644 --- a/base/logging.cc +++ b/base/logging.cc @@ -27,17 +27,39 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "build/build_config.h" + +#if defined(WIN32) +#include <windows.h> +typedef HANDLE FileHandle; +typedef HANDLE MutexHandle; +#endif + +#if defined(OS_MACOSX) +#include <CoreFoundation/CoreFoundation.h> +#include <mach/mach.h> +#include <mach/mach_time.h> +#include <mach-o/dyld.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#define MAX_PATH PATH_MAX +typedef FILE* FileHandle; +typedef pthread_mutex_t* MutexHandle; +#endif + #include <ctime> #include <iomanip> #include <cstring> -#include <windows.h> #include <algorithm> #include "base/base_switches.h" #include "base/command_line.h" #include "base/lock_impl.h" #include "base/logging.h" +#include "base/string_util.h" #include "base/sys_string_conversions.h" - + namespace logging { bool g_enable_dcheck = false; @@ -55,10 +77,15 @@ char* log_filter_prefix = NULL; // which log file to use? This is initialized by InitLogging or // will be lazily initialized to the default value when it is // first needed. -wchar_t log_file_name[MAX_PATH] = { 0 }; +#if defined(OS_WIN) +typedef wchar_t PathChar; +#else +typedef char PathChar; +#endif +PathChar log_file_name[MAX_PATH] = { 0 }; // this file is lazily opened and the handle may be NULL -HANDLE log_file = NULL; +FileHandle log_file = NULL; // what should be prepended to each message? bool log_process_id = false; @@ -77,7 +104,59 @@ static LockImpl* log_lock = NULL; // When we don't use a lock, we are using a global mutex. We need to do this // because LockFileEx is not thread safe. -HANDLE log_mutex = NULL; +#if defined(OS_WIN) +MutexHandle log_mutex = NULL; +#elif defined(OS_POSIX) +pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +// Helper functions to wrap platform differences. + +int32 CurrentProcessId() { +#if defined(OS_WIN) + return GetCurrentProcessId(); +#elif defined(OS_POSIX) + return getpid(); +#endif +} + +int32 CurrentThreadId() { +#if defined(OS_WIN) + return GetCurrentThreadId(); +#elif defined(OS_MACOSX) + return mach_thread_self(); +#else + // TODO(pinkerton): need linux-fu to fill in thread id here + return 0; +#endif +} + +uint64 TickCount() { +#if defined(OS_WIN) + return GetTickCount(); +#elif defined(OS_MACOSX) + return mach_absolute_time(); +#else + // TODO(pinkerton): need linux-fu to fill in time here + return 0; +#endif +} + +void CloseFile(FileHandle log) { +#if defined(OS_WIN) + CloseHandle(log); +#else + fclose(log); +#endif +} + +void DeleteFile(PathChar* log_name) { +#if defined(OS_WIN) + DeleteFile(log_name); +#else + unlink(log_name); +#endif +} // Called by logging functions to ensure that debug_file is initialized // and can be used for writing. Returns false if the file could not be @@ -86,13 +165,14 @@ bool InitializeLogFileHandle() { if (log_file) return true; +#if defined(OS_WIN) if (!log_file_name[0]) { // nobody has called InitLogging to specify a debug log file, so here we // initialize the log file name to the default GetModuleFileName(NULL, log_file_name, MAX_PATH); wchar_t* last_backslash = wcsrchr(log_file_name, '\\'); if (last_backslash) - last_backslash[1] = 0; // name now ends with the backslash + last_backslash[1] = 0; // name now ends with the backslash wcscat_s(log_file_name, L"debug.log"); } @@ -110,10 +190,34 @@ bool InitializeLogFileHandle() { } } SetFilePointer(log_file, 0, 0, FILE_END); +#elif defined(OS_POSIX) + if (!log_file_name[0]) { +#if defined(OS_MACOSX) + // nobody has called InitLogging to specify a debug log file, so here we + // initialize the log file name to the default + uint32_t log_file_name_size = arraysize(log_file_name); + _NSGetExecutablePath(log_file_name, &log_file_name_size); + char* last_slash = strrchr(log_file_name, '/'); + if (last_slash) + last_slash[1] = 0; // name now ends with the slash + strlcat(log_file_name, "debug.log", arraysize(log_file_name)); +#endif + } + + log_file = fopen(log_file_name, "a"); + if (log_file == NULL) { + // try the current directory + log_file = fopen("debug.log", "a"); + if (log_file == NULL) { + return false; + } + } +#endif return true; } void InitLogMutex() { +#if defined(OS_WIN) if (!log_mutex) { // \ is not a legal character in mutex names so we replace \ with / std::wstring safe_name(log_file_name); @@ -122,16 +226,19 @@ void InitLogMutex() { t.append(safe_name); log_mutex = ::CreateMutex(NULL, FALSE, t.c_str()); } +#elif defined(OS_POSIX) + // statically initialized +#endif } -void InitLogging(const wchar_t* new_log_file, LoggingDestination logging_dest, +void InitLogging(const PathChar* new_log_file, LoggingDestination logging_dest, LogLockingState lock_log, OldFileDeletionState delete_old) { g_enable_dcheck = CommandLine().HasSwitch(switches::kEnableDCHECK); if (log_file) { // calling InitLogging twice or after some log call has already opened the // default log file will re-initialize to the new options - CloseHandle(log_file); + CloseFile(log_file); log_file = NULL; } @@ -143,7 +250,11 @@ void InitLogging(const wchar_t* new_log_file, LoggingDestination logging_dest, logging_destination == LOG_ONLY_TO_SYSTEM_DEBUG_LOG) return; +#if defined(OS_WIN) wcscpy_s(log_file_name, MAX_PATH, new_log_file); +#elif defined(OS_POSIX) + strlcpy(log_file_name, new_log_file, arraysize(log_file_name)); +#endif if (delete_old == DELETE_OLD_LOG_FILE) DeleteFile(log_file_name); @@ -173,7 +284,11 @@ void SetLogFilterPrefix(const char* filter) { if (filter) { size_t size = strlen(filter)+1; log_filter_prefix = new char[size]; +#if defined(OS_WIN) strcpy_s(log_filter_prefix, size, filter); +#elif defined(OS_POSIX) + strlcpy(log_filter_prefix, filter, size); +#endif } } @@ -200,6 +315,7 @@ void DisplayDebugMessage(const std::string& str) { if (str.empty()) return; +#if defined(OS_WIN) // look for the debug dialog program next to our application wchar_t prog_name[MAX_PATH]; GetModuleFileNameW(NULL, prog_name, MAX_PATH); @@ -228,6 +344,9 @@ void DisplayDebugMessage(const std::string& str) { MessageBoxW(NULL, cmdline, L"Fatal error", MB_OK | MB_ICONHAND | MB_TOPMOST); } +#else + fprintf(stderr, "%s\n", str.c_str()); +#endif } LogMessage::LogMessage(const char* file, int line, LogSeverity severity, @@ -263,9 +382,9 @@ void LogMessage::Init(const char* file, int line) { stream_ << '['; if (log_process_id) - stream_ << GetCurrentProcessId() << ':'; + stream_ << CurrentProcessId() << ':'; if (log_thread_id) - stream_ << GetCurrentThreadId() << ':'; + stream_ << CurrentThreadId() << ':'; if (log_timestamp) { time_t t = time(NULL); #if _MSC_VER >= 1400 @@ -285,7 +404,7 @@ void LogMessage::Init(const char* file, int line) { << ':'; } if (log_tickcount) - stream_ << GetTickCount() << ':'; + stream_ << TickCount() << ':'; stream_ << log_severity_names[severity_] << ":" << file << "(" << line << ")] "; message_start_ = stream_.tellp(); @@ -307,9 +426,14 @@ LogMessage::~LogMessage() { } if (logging_destination == LOG_ONLY_TO_SYSTEM_DEBUG_LOG || - logging_destination == LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) + logging_destination == LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) { +#if defined(OS_WIN) OutputDebugStringA(str_newline.c_str()); - +#else + fprintf(stderr, str_newline.c_str()); +#endif + } + // write to log file if (logging_destination != LOG_NONE && logging_destination != LOG_ONLY_TO_SYSTEM_DEBUG_LOG && @@ -321,8 +445,12 @@ LogMessage::~LogMessage() { // call InitLogging. This is not thread safe. See below InitLogMutex(); +#if defined(OS_WIN) DWORD r = ::WaitForSingleObject(log_mutex, INFINITE); DCHECK(r != WAIT_ABANDONED); +#elif defined(OS_POSIX) + pthread_mutex_lock(&log_mutex); +#endif } else { // use the lock if (!log_lock) { @@ -336,12 +464,20 @@ LogMessage::~LogMessage() { log_lock->Lock(); } +#if defined(OS_WIN) SetFilePointer(log_file, 0, 0, SEEK_END); DWORD num_written; WriteFile(log_file, (void*)str_newline.c_str(), (DWORD)str_newline.length(), &num_written, NULL); +#else + fprintf(log_file, "%s", str_newline.c_str()); +#endif if (lock_log_file == LOCK_LOG_FILE) { +#if defined(OS_WIN) ReleaseMutex(log_mutex); +#elif defined(OS_POSIX) + pthread_mutex_unlock(&log_mutex); +#endif } else { log_lock->Unlock(); } @@ -349,9 +485,13 @@ LogMessage::~LogMessage() { if (severity_ == LOG_FATAL) { // display a message or break into the debugger on a fatal error +#if defined(OS_WIN) if (::IsDebuggerPresent()) { __debugbreak(); - } else { + } + else +#endif + { if (log_assert_handler) { // make a copy of the string for the handler out of paranoia log_assert_handler(std::string(stream_.str())); @@ -360,7 +500,16 @@ LogMessage::~LogMessage() { // the debug message process DisplayDebugMessage(stream_.str()); // Crash the process to generate a dump. +#if defined(OS_WIN) __debugbreak(); +#elif defined(OS_POSIX) +#if defined(OS_MACOSX) + // TODO: when we have breakpad support, generate a breakpad dump, but + // until then, do not invoke the Apple crash reporter. + Debugger(); +#endif + exit(-1); +#endif } } } @@ -370,7 +519,7 @@ void CloseLogFile() { if (!log_file) return; - CloseHandle(log_file); + CloseFile(log_file); log_file = NULL; } |