diff options
Diffstat (limited to 'kwin/tools/xreply/xreply.c')
-rw-r--r-- | kwin/tools/xreply/xreply.c | 197 |
1 files changed, 0 insertions, 197 deletions
diff --git a/kwin/tools/xreply/xreply.c b/kwin/tools/xreply/xreply.c deleted file mode 100644 index ecdf6ebc3..000000000 --- a/kwin/tools/xreply/xreply.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - - LD_PRELOAD library that gives statistic on number of roundtrips in an application. - - $XREPLY_BACKTRACE defines whether and how backtraces will be printed for every - roundtrip. If not set, only total number of roundtrips is printed after the process - exits. If set to a number, backtrace for every roundtrip will be printed, and the - backtraces will be as deep as the given number. If set to C<number> (e.g. C10), - the backtraces will be "compressed" - every backtrace will be printed only once - after the process exits, together with number of times it occured. - -*/ - -#define _GNU_SOURCE -#include <dlfcn.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <execinfo.h> -#include <assert.h> -#include <X11/Xlibint.h> - -/* Since these symbols are weak, the apps can provide their own, and therefore - e.g. temporarily suspend counting of roundtrips. At least theoretically, - I haven't really tried it. -*/ -__attribute((weak)) long ___xreply_reply_count = 0; -__attribute((weak)) int ___xreply_reply_enabled = 1; - -#define MAX_BACKTRACES 1024 - -extern long ___xreply_reply_count; -extern int ___xreply_reply_enabled; - -typedef Status (*xreply_ptr_t)(Display*,xReply*,int,Bool); - -static xreply_ptr_t xreply_ptr = NULL; -static int xreply_backtrace_set = 0; -static int xreply_backtrace_type = 0; - -struct xreply_struct - { - char* key; - char* text; - int count; - }; -static struct xreply_struct backtraces[ MAX_BACKTRACES ]; -static int backtraces_size = 0; - -static int xreply_compare( const void* left, const void* right ) - { - int left_count = ((struct xreply_struct*)left)->count; - int right_count = ((struct xreply_struct*)right)->count; - return right_count - left_count; - } - -static void xreply_print(void) - { - char tmp[ 1024 ]; - int fd; - fd = open( "/proc/self/cmdline", O_RDONLY ); - if( fd >= 0 ) - { - read( fd, tmp, 1024 ); - tmp[ 1023 ] = '\0'; - close( fd ); - } - fprintf( stderr, "XREPLY (%d : %s): %ld\n", getpid(), tmp, ___xreply_reply_count ); - if( xreply_backtrace_type < 0 ) - { - int i; - qsort( backtraces, backtraces_size, sizeof( struct xreply_struct ), xreply_compare ); - for( i = 0; - i < backtraces_size; - ++i ) - fprintf( stderr, "%d:%s\n\n", backtraces[ i ].count, backtraces[ i ].text ); - } - } - -static void xreply_backtrace() - { - void* trace[256]; - int n = backtrace(trace, 256); - char** strings = backtrace_symbols (trace, n); - - if( xreply_backtrace_type > 0 ) - { - fprintf( stderr, "%ld [\n", ___xreply_reply_count ); - if( n > xreply_backtrace_type ) - n = xreply_backtrace_type; - int i; - for( i = 0; - i < n; - ++i ) - fprintf( stderr, "%d: %s\n", i, strings[ i ] ); - fprintf( stderr, "]\n" ); - } - else - { - char stack[ 256 * 20 ]; - int pos = 0; - int i; - stack[ 0 ] = '\0'; - if( n > -xreply_backtrace_type ) - n = -xreply_backtrace_type; - for( i = 0; - i < n; - ++i ) - { - const char* start = strrchr( strings[ i ], '[' ); - if( start == NULL ) - assert( !"No [ in address." ); - long addr; - if( sscanf( start + 1, "0x%lx", &addr ) != 1 ) - assert( !"Failed to parse address." ); - if( sizeof( void* ) == 4 ) - { - sprintf( stack + pos, "0x%8lx", addr ); - pos += 10; - } - else if( sizeof( void* ) == 8 ) - { - sprintf( stack + pos, "0x%16lx", addr ); - pos += 18; - } - else - assert( !"Unknown sizeof( void* )." ); - } - for( i = 0; - i < backtraces_size; - ++i ) - if( strcmp( backtraces[ i ].key, stack ) == 0 ) - { - ++backtraces[ i ].count; - break; - } - if( i == backtraces_size ) - { - int stack_text_size = 10; - char* stack_text; - char* stack_text_pos; - for( i = 0; - i < n; - ++i ) - stack_text_size += strlen( strings[ i ] ) + 5; - stack_text = stack_text_pos = malloc( stack_text_size ); - for( i = 0; - i < n; - ++i ) - { - stack_text_pos = stpcpy( stack_text_pos, "\n" ); - stack_text_pos = stpcpy( stack_text_pos, strings[ i ] ); - } - backtraces[ backtraces_size ].key = strdup( stack ); - backtraces[ backtraces_size ].text = stack_text; - backtraces[ backtraces_size ].count = 1; - ++backtraces_size; - if( backtraces_size >= MAX_BACKTRACES ) - assert( !"MAX_BACKTRACES reached." ); - } - } - free (strings); - } - -Status -_XReply (dpy, rep, extra, discard) - register Display *dpy; - register xReply *rep; - int extra; /* number of 32-bit words expected after the reply */ - Bool discard; /* should I discard data following "extra" words? */ - { - if( ___xreply_reply_enabled ) - ++___xreply_reply_count; - if( xreply_backtrace_set == 0 ) - { - if( getenv( "XREPLY_BACKTRACE" ) != NULL ) - { // C<number> - compress backtraces, saved as negative value in xreply_backtrace_type - if( getenv( "XREPLY_BACKTRACE" )[ 0 ] == 'C' ) - xreply_backtrace_type = -atoi( getenv( "XREPLY_BACKTRACE" ) + 1 ); - else // <number> - print the backtrace every time - xreply_backtrace_type = atoi( getenv( "XREPLY_BACKTRACE" )); - } - else - xreply_backtrace_type = 0; - } - if( xreply_backtrace_type != 0 ) - xreply_backtrace(); - if( xreply_ptr == NULL ) - { - xreply_ptr = (xreply_ptr_t)dlsym( RTLD_NEXT, "_XReply" ); - if( xreply_ptr == NULL ) - assert( !"dlsym() failed." ); - atexit( xreply_print ); - } - return xreply_ptr( dpy, rep, extra, discard ); - } |