diff options
author | 2020-08-03 14:33:06 +0000 | |
---|---|---|
committer | 2020-08-03 14:33:06 +0000 | |
commit | 061da546b983eb767bad15e67af1174fb0bcf31c (patch) | |
tree | 83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/tools/debugserver/source/DNBLog.cpp | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/tools/debugserver/source/DNBLog.cpp')
-rw-r--r-- | gnu/llvm/lldb/tools/debugserver/source/DNBLog.cpp | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/tools/debugserver/source/DNBLog.cpp b/gnu/llvm/lldb/tools/debugserver/source/DNBLog.cpp new file mode 100644 index 00000000000..11b2d0a04b7 --- /dev/null +++ b/gnu/llvm/lldb/tools/debugserver/source/DNBLog.cpp @@ -0,0 +1,268 @@ +//===-- DNBLog.cpp ----------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// 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 "PThreadMutex.h" +#include <mach/mach.h> +#include <pthread.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/time.h> +#include <unistd.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 |