summaryrefslogtreecommitdiff
path: root/tools/debugserver/source/DNBLog.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-01-06 20:12:03 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-01-06 20:12:03 +0000
commit9e6d35490a6542f9c97607f93c2ef8ca8e03cbcc (patch)
treedd2a1ddf0476664c2b823409c36cbccd52662ca7 /tools/debugserver/source/DNBLog.cpp
parent3bd2e91faeb9eeec1aae82c64a3253afff551cfd (diff)
Notes
Diffstat (limited to 'tools/debugserver/source/DNBLog.cpp')
-rw-r--r--tools/debugserver/source/DNBLog.cpp377
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