From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/lib/direct/debug.c | 430 +++++++++++++++++++++++++++++++++++++ 1 file changed, 430 insertions(+) create mode 100755 Source/DirectFB/lib/direct/debug.c (limited to 'Source/DirectFB/lib/direct/debug.c') diff --git a/Source/DirectFB/lib/direct/debug.c b/Source/DirectFB/lib/direct/debug.c new file mode 100755 index 0000000..6aad0a1 --- /dev/null +++ b/Source/DirectFB/lib/direct/debug.c @@ -0,0 +1,430 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +#if DIRECT_BUILD_TEXT + +#if DIRECT_BUILD_DEBUGS /* Build with debug support? */ + +typedef struct { + DirectLink link; + char *name; + bool enabled; +} DebugDomainEntry; + +/**************************************************************************************************/ + +static pthread_mutex_t domains_lock = PTHREAD_MUTEX_INITIALIZER; +static unsigned int domains_age = 1; +static DirectLink *domains = NULL; + +/**************************************************************************************************/ + +__attribute__((no_instrument_function)) +static inline DebugDomainEntry * +lookup_domain( const char *name, bool sub ) +{ + DebugDomainEntry *entry; + + direct_list_foreach (entry, domains) { + if (! strcasecmp( entry->name, name )) + return entry; + } + + /* + * If the domain being registered contains a slash, but didn't exactly match an entry + * in directfbrc, check to see if the domain is descended from an entry in directfbrc + * (e.g. 'ui/field/messages' matches 'ui' or 'ui/field') + */ + if (sub && strchr(name, '/')) { + int passed_name_len = strlen( name ); + + direct_list_foreach (entry, domains) { + int entry_len = strlen( entry->name ); + if ((passed_name_len > entry_len) && + (name[entry_len] == '/') && + (! strncasecmp( entry->name, name, entry_len))) { + return entry; + } + } + } + + return NULL; +} + +__attribute__((no_instrument_function)) +static inline bool +check_domain( DirectDebugDomain *domain ) +{ + if (domain->age != domains_age) { + DebugDomainEntry *entry = lookup_domain( domain->name, true ); + + domain->age = domains_age; + + if (entry) { + domain->registered = true; + domain->enabled = entry->enabled; + } + } + + return domain->registered ? domain->enabled : direct_config->debug; +} + +#endif /* DIRECT_BUILD_DEBUGS */ + +/**************************************************************************************************/ + +void +direct_debug_config_domain( const char *name, bool enable ) +{ +#if DIRECT_BUILD_DEBUGS /* Build with debug support? */ + DebugDomainEntry *entry; + + pthread_mutex_lock( &domains_lock ); + + entry = lookup_domain( name, false ); + if (!entry) { + entry = calloc( 1, sizeof(DebugDomainEntry) ); + if (!entry) { + D_WARN( "out of memory" ); + pthread_mutex_unlock( &domains_lock ); + return; + } + + entry->name = strdup( name ); + + direct_list_prepend( &domains, &entry->link ); + } + + entry->enabled = enable; + + if (! ++domains_age) + domains_age++; + + pthread_mutex_unlock( &domains_lock ); +#endif /* DIRECT_BUILD_DEBUGS */ +} + +/**************************************************************************************************/ + +__attribute__((no_instrument_function)) +static inline void +debug_domain_vprintf( const char *name, + int name_len, + const char *format, + va_list ap ) +{ + char buf[512]; + long long millis = direct_clock_get_millis(); + const char *thread = direct_thread_self_name(); + int indent = direct_trace_debug_indent() * 4; + + /* Prepare user message. */ + vsnprintf( buf, sizeof(buf), format, ap ); + + /* Fill up domain name column after the colon, prepending remaining space (excl. ': ') to indent. */ + indent += (name_len < 20 ? 20 : 36) - name_len - 2; + + /* Print full message. */ + direct_log_printf( NULL, "(-) [%-15s %3lld.%03lld] (%5d) %s: %*s%s", thread ? thread : " NO NAME", + millis / 1000LL, millis % 1000LL, direct_gettid(), name, indent, "", buf ); +} + +#if DIRECT_BUILD_DEBUGS /* Build with debug support? */ + +__attribute__((no_instrument_function)) +void +direct_debug( const char *format, ... ) +{ + va_list ap; + + va_start( ap, format ); + + debug_domain_vprintf( "- - ", 4, format, ap ); + + va_end( ap ); +} + +__attribute__((no_instrument_function)) +void +direct_debug_at( DirectDebugDomain *domain, + const char *format, ... ) +{ + bool enabled; + + pthread_mutex_lock( &domains_lock ); + + enabled = check_domain( domain ); + + pthread_mutex_unlock( &domains_lock ); + + if (enabled) { + va_list ap; + + va_start( ap, format ); + + debug_domain_vprintf( domain->name, domain->name_len, format, ap ); + + va_end( ap ); + } +} + +#endif /* DIRECT_BUILD_DEBUGS */ + +__attribute__((no_instrument_function)) +void +direct_debug_at_always( DirectDebugDomain *domain, + const char *format, ... ) +{ + va_list ap; + + va_start( ap, format ); + + debug_domain_vprintf( domain->name, domain->name_len, format, ap ); + + va_end( ap ); +} + +#if DIRECT_BUILD_DEBUGS /* Build with debug support? */ + +__attribute__((no_instrument_function)) +void +direct_debug_enter( DirectDebugDomain *domain, + const char *func, + const char *file, + int line, + const char *format, ... ) +{ + bool enabled; + + pthread_mutex_lock( &domains_lock ); + + enabled = check_domain( domain ); + + pthread_mutex_unlock( &domains_lock ); + + if (enabled) { + int len; + char dom[48]; + char fmt[128]; + char buf[512]; + long long millis = direct_clock_get_millis(); + const char *name = direct_thread_self_name(); + va_list ap; + + va_start( ap, format ); + + vsnprintf( buf, sizeof(buf), format, ap ); + + va_end( ap ); + + + len = snprintf( dom, sizeof(dom), "%s:", domain->name ); + + if (len < 18) + len = 18; + else + len = 28; + + len += direct_trace_debug_indent() * 4; + + snprintf( fmt, sizeof(fmt), "(>) [%%-15s %%3lld.%%03lld] (%%5d) %%-%ds Entering %%s%%s [%%s:%%d]\n", len ); + + direct_log_printf( NULL, fmt, name ? name : " NO NAME ", + millis / 1000LL, millis % 1000LL, direct_gettid(), dom, + func, buf, file, line ); + } +} + +__attribute__((no_instrument_function)) +void +direct_debug_exit( DirectDebugDomain *domain, + const char *func, + const char *file, + int line, + const char *format, ... ) +{ + bool enabled; + + pthread_mutex_lock( &domains_lock ); + + enabled = check_domain( domain ); + + pthread_mutex_unlock( &domains_lock ); + + if (enabled) { + int len; + char dom[48]; + char fmt[128]; + char buf[512]; + long long millis = direct_clock_get_millis(); + const char *name = direct_thread_self_name(); + va_list ap; + + va_start( ap, format ); + + vsnprintf( buf, sizeof(buf), format, ap ); + + va_end( ap ); + + + len = snprintf( dom, sizeof(dom), "%s:", domain->name ); + + if (len < 18) + len = 18; + else + len = 28; + + len += direct_trace_debug_indent() * 4; + + snprintf( fmt, sizeof(fmt), "(<) [%%-15s %%3lld.%%03lld] (%%5d) %%-%ds Returning from %%s%%s [%%s:%%d]\n", len ); + + direct_log_printf( NULL, fmt, name ? name : " NO NAME ", + millis / 1000LL, millis % 1000LL, direct_gettid(), dom, + func, buf, file, line ); + } +} + +__attribute__((no_instrument_function)) +static void +trap( const char *domain ) +{ + D_DEBUG( "Direct/%s: Raising SIGTRAP...\n", domain ); + + raise( SIGTRAP ); + + D_DEBUG( "Direct/%s: ...didn't catch signal on my own, calling killpg().\n", domain ); + + kill( direct_gettid(), SIGTRAP ); + + D_DEBUG( "Direct/%s: ...still running, calling pthread_exit().\n", domain ); + + pthread_exit( NULL ); +} + +__attribute__((no_instrument_function)) +void +direct_break( const char *func, + const char *file, + int line, + const char *format, ... ) +{ + char buf[512]; + long long millis = direct_clock_get_millis(); + const char *name = direct_thread_self_name(); + + va_list ap; + + va_start( ap, format ); + + vsnprintf( buf, sizeof(buf), format, ap ); + + va_end( ap ); + + direct_log_printf( NULL, + "(!) [%-15s %3lld.%03lld] (%5d) *** Break [%s] *** [%s:%d in %s()]\n", + name ? name : " NO NAME ", millis / 1000LL, millis % 1000LL, + direct_gettid(), buf, file, line, func ); + + direct_trace_print_stack( NULL ); + + if (direct_config->fatal_break) + trap( "Break" ); +} + +__attribute__((no_instrument_function)) +void +direct_assertion( const char *exp, + const char *func, + const char *file, + int line ) +{ + long long millis = direct_clock_get_millis(); + const char *name = direct_thread_self_name(); + + direct_log_printf( NULL, + "(!) [%-15s %3lld.%03lld] (%5d) *** Assertion [%s] failed *** [%s:%d in %s()]\n", + name ? name : " NO NAME ", millis / 1000LL, millis % 1000LL, + direct_gettid(), exp, file, line, func ); + + direct_trace_print_stack( NULL ); + + if (direct_config->fatal >= DCFL_ASSERT) + trap( "Assertion" ); +} + +__attribute__((no_instrument_function)) +void +direct_assumption( const char *exp, + const char *func, + const char *file, + int line ) +{ + long long millis = direct_clock_get_millis(); + const char *name = direct_thread_self_name(); + + direct_log_printf( NULL, + "(!) [%-15s %3lld.%03lld] (%5d) *** Assumption [%s] failed *** [%s:%d in %s()]\n", + name ? name : " NO NAME ", millis / 1000LL, millis % 1000LL, + direct_gettid(), exp, file, line, func ); + + direct_trace_print_stack( NULL ); + + if (direct_config->fatal >= DCFL_ASSUME) + trap( "Assumption" ); +} + +#endif /* DIRECT_BUILD_DEBUGS */ + +#else + +void +direct_debug_config_domain( const char *name, bool enable ) +{ +} + +#endif /* DIRECT_BUILD_TEXT */ + -- cgit