diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:12:03 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:12:03 +0000 |
commit | 9e6d35490a6542f9c97607f93c2ef8ca8e03cbcc (patch) | |
tree | dd2a1ddf0476664c2b823409c36cbccd52662ca7 /tools/debugserver/source/DNBLog.cpp | |
parent | 3bd2e91faeb9eeec1aae82c64a3253afff551cfd (diff) |
Notes
Diffstat (limited to 'tools/debugserver/source/DNBLog.cpp')
-rw-r--r-- | tools/debugserver/source/DNBLog.cpp | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/tools/debugserver/source/DNBLog.cpp b/tools/debugserver/source/DNBLog.cpp new file mode 100644 index 0000000000000..18d8d2ad3a674 --- /dev/null +++ b/tools/debugserver/source/DNBLog.cpp @@ -0,0 +1,377 @@ +//===-- DNBLog.cpp ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Created by Greg Clayton on 6/18/07. +// +//===----------------------------------------------------------------------===// + +#include "DNBLog.h" + +static int g_debug = 0; +static int g_verbose = 0; + +#if defined (DNBLOG_ENABLED) + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <sys/time.h> +#include <unistd.h> +#include <mach/mach.h> +#include <pthread.h> +#include "PThreadMutex.h" + +uint32_t g_log_bits = 0; +static DNBCallbackLog g_log_callback = NULL; +static void *g_log_baton = NULL; + + +int +DNBLogGetDebug () +{ + return g_debug; +} + + +void +DNBLogSetDebug (int g) +{ + g_debug = g; +} + +int +DNBLogGetVerbose () +{ + return g_verbose; +} + +void +DNBLogSetVerbose (int v) +{ + g_verbose = v; +} + +bool +DNBLogCheckLogBit (uint32_t bit) +{ + return (g_log_bits & bit) != 0; +} + +uint32_t +DNBLogSetLogMask (uint32_t mask) +{ + uint32_t old = g_log_bits; + g_log_bits = mask; + return old; +} + +uint32_t +DNBLogGetLogMask () +{ + return g_log_bits; +} + +void +DNBLogSetLogCallback (DNBCallbackLog callback, void *baton) +{ + g_log_callback = callback; + g_log_baton = baton; +} + +DNBCallbackLog +DNBLogGetLogCallback () +{ + return g_log_callback; +} + +bool +DNBLogEnabled () +{ + return g_log_callback != NULL; +} + +bool +DNBLogEnabledForAny (uint32_t mask) +{ + if (g_log_callback) + return (g_log_bits & mask) != 0; + return false; +} +static inline void +_DNBLogVAPrintf(uint32_t flags, const char *format, va_list args) +{ + static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE); + PTHREAD_MUTEX_LOCKER(locker, g_LogThreadedMutex); + + if (g_log_callback) + g_log_callback(g_log_baton, flags, format, args); +} + +void +_DNBLog(uint32_t flags, const char *format, ...) +{ + va_list args; + va_start (args, format); + _DNBLogVAPrintf(flags, format, args); + va_end (args); +} + +//---------------------------------------------------------------------- +// Print debug strings if and only if the global g_debug is set to +// a non-zero value. +//---------------------------------------------------------------------- +void +_DNBLogDebug (const char *format, ...) +{ + if (DNBLogEnabled () && g_debug) + { + va_list args; + va_start (args, format); + _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG, format, args); + va_end (args); + } +} + + +//---------------------------------------------------------------------- +// Print debug strings if and only if the global g_debug is set to +// a non-zero value. +//---------------------------------------------------------------------- +void +_DNBLogDebugVerbose (const char *format, ...) +{ + if (DNBLogEnabled () && g_debug && g_verbose) + { + va_list args; + va_start (args, format); + _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG | DNBLOG_FLAG_VERBOSE, format, args); + va_end (args); + } +} + + +static uint32_t g_message_id = 0; + +//---------------------------------------------------------------------- +// Prefix the formatted log string with process and thread IDs and +// suffix it with a newline. +//---------------------------------------------------------------------- +void +_DNBLogThreaded (const char *format, ...) +{ + if (DNBLogEnabled ()) + { + //PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex()); + + char *arg_msg = NULL; + va_list args; + va_start (args, format); + ::vasprintf (&arg_msg, format, args); + va_end (args); + + if (arg_msg != NULL) + { + static struct timeval g_timeval = { 0 , 0 }; + static struct timeval tv; + static struct timeval delta; + gettimeofday(&tv, NULL); + if (g_timeval.tv_sec == 0) + { + delta.tv_sec = 0; + delta.tv_usec = 0; + } + else + { + timersub (&tv, &g_timeval, &delta); + } + g_timeval = tv; + + // Calling "mach_port_deallocate()" bumps the reference count on the thread + // port, so we need to deallocate it. mach_task_self() doesn't bump the ref + // count. + thread_port_t thread_self = mach_thread_self(); + + _DNBLog (DNBLOG_FLAG_THREADED, "%u +%lu.%06u sec [%4.4x/%4.4x]: %s", + ++g_message_id, + delta.tv_sec, + delta.tv_usec, + getpid(), + thread_self, + arg_msg); + + mach_port_deallocate(mach_task_self(), thread_self); + free (arg_msg); + } + } +} + +//---------------------------------------------------------------------- +// Prefix the formatted log string with process and thread IDs and +// suffix it with a newline. +//---------------------------------------------------------------------- +void +_DNBLogThreadedIf (uint32_t log_bit, const char *format, ...) +{ + if (DNBLogEnabled () && (log_bit & g_log_bits) == log_bit) + { + //PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex()); + + char *arg_msg = NULL; + va_list args; + va_start (args, format); + ::vasprintf (&arg_msg, format, args); + va_end (args); + + if (arg_msg != NULL) + { + static struct timeval g_timeval = { 0 , 0 }; + static struct timeval tv; + static struct timeval delta; + gettimeofday(&tv, NULL); + if (g_timeval.tv_sec == 0) + { + delta.tv_sec = 0; + delta.tv_usec = 0; + } + else + { + timersub (&tv, &g_timeval, &delta); + } + g_timeval = tv; + + // Calling "mach_port_deallocate()" bumps the reference count on the thread + // port, so we need to deallocate it. mach_task_self() doesn't bump the ref + // count. + thread_port_t thread_self = mach_thread_self(); + + _DNBLog (DNBLOG_FLAG_THREADED, "%u +%lu.%06u sec [%4.4x/%4.4x]: %s", + ++g_message_id, + delta.tv_sec, + delta.tv_usec, + getpid(), + thread_self, + arg_msg); + + mach_port_deallocate(mach_task_self(), thread_self); + + free (arg_msg); + } + } +} + + + +//---------------------------------------------------------------------- +// Printing of errors that are not fatal. +//---------------------------------------------------------------------- +void +_DNBLogError (const char *format, ...) +{ + if (DNBLogEnabled ()) + { + char *arg_msg = NULL; + va_list args; + va_start (args, format); + ::vasprintf (&arg_msg, format, args); + va_end (args); + + if (arg_msg != NULL) + { + _DNBLog (DNBLOG_FLAG_ERROR, "error: %s", arg_msg); + free (arg_msg); + } + } +} + +//---------------------------------------------------------------------- +// Printing of errors that ARE fatal. Exit with ERR exit code +// immediately. +//---------------------------------------------------------------------- +void +_DNBLogFatalError (int err, const char *format, ...) +{ + if (DNBLogEnabled ()) + { + char *arg_msg = NULL; + va_list args; + va_start (args, format); + ::vasprintf (&arg_msg, format, args); + va_end (args); + + if (arg_msg != NULL) + { + _DNBLog (DNBLOG_FLAG_ERROR | DNBLOG_FLAG_FATAL, "error: %s", arg_msg); + free (arg_msg); + } + ::exit (err); + } +} + + +//---------------------------------------------------------------------- +// Printing of warnings that are not fatal only if verbose mode is +// enabled. +//---------------------------------------------------------------------- +void +_DNBLogVerbose (const char *format, ...) +{ + if (DNBLogEnabled () && g_verbose) + { + va_list args; + va_start (args, format); + _DNBLogVAPrintf(DNBLOG_FLAG_VERBOSE, format, args); + va_end (args); + } +} + +//---------------------------------------------------------------------- +// Printing of warnings that are not fatal only if verbose mode is +// enabled. +//---------------------------------------------------------------------- +void +_DNBLogWarningVerbose (const char *format, ...) +{ + if (DNBLogEnabled () && g_verbose) + { + char *arg_msg = NULL; + va_list args; + va_start (args, format); + ::vasprintf (&arg_msg, format, args); + va_end (args); + + if (arg_msg != NULL) + { + _DNBLog (DNBLOG_FLAG_WARNING | DNBLOG_FLAG_VERBOSE, "warning: %s", arg_msg); + free (arg_msg); + } + } +} +//---------------------------------------------------------------------- +// Printing of warnings that are not fatal. +//---------------------------------------------------------------------- +void +_DNBLogWarning (const char *format, ...) +{ + if (DNBLogEnabled ()) + { + char *arg_msg = NULL; + va_list args; + va_start (args, format); + ::vasprintf (&arg_msg, format, args); + va_end (args); + + if (arg_msg != NULL) + { + _DNBLog (DNBLOG_FLAG_WARNING, "warning: %s", arg_msg); + free (arg_msg); + } + } +} + +#endif |