[Assorted-commits] SF.net SVN: assorted:[1433] sandbox/trunk/src/nix/btmalloc
Brought to you by:
yangzhang
From: <yan...@us...> - 2009-05-25 18:31:58
|
Revision: 1433 http://assorted.svn.sourceforge.net/assorted/?rev=1433&view=rev Author: yangzhang Date: 2009-05-25 18:31:33 +0000 (Mon, 25 May 2009) Log Message: ----------- also added evan's backtracing method ('lite') Modified Paths: -------------- sandbox/trunk/src/nix/btmalloc/run.bash Added Paths: ----------- sandbox/trunk/src/nix/btmalloc/btlite.c sandbox/trunk/src/nix/btmalloc/btmalloclite.c sandbox/trunk/src/nix/btmalloc/symbolize.py Added: sandbox/trunk/src/nix/btmalloc/btlite.c =================================================================== --- sandbox/trunk/src/nix/btmalloc/btlite.c (rev 0) +++ sandbox/trunk/src/nix/btmalloc/btlite.c 2009-05-25 18:31:33 UTC (rev 1433) @@ -0,0 +1,52 @@ +/* +Preload library to print a stack trace when crashing. + +Evan Jones <ev...@mi...> +March, 2008. + +Based on a version written by Mark Hahn, SHARCnet, 2007. + +Obtained from the beowulf mailing list: +http://article.gmane.org/gmane.comp.clustering.beowulf.general/18463 + +Compile: +gcc -fPIC backtrace.c -shared -o backtrace.so + +Use: +LD_PRELOAD=./backtrace.so ./tester + +Then use addr2line to translate addresses into file/line numbers. + +TODO: +Use some DWARF library to translate addresses into file and line numbers. +Mark Hahn's code linked above uses libbfd. +*/ + +#include <execinfo.h> +#include <signal.h> +#include <unistd.h> + +#define MAX_FRAMES (20) + +static void handler(int sig) { + static const char MESSAGE[] = "\n\nSTACK TRACE:\n"; + write(0, MESSAGE, sizeof(MESSAGE)); + + void* array[MAX_FRAMES]; + size_t size = backtrace(array, sizeof(array)/sizeof(*array)); + backtrace_symbols_fd(array, size, 0); + + // Kill ourselves to propagate the error + raise(sig); +} + +static void __attribute__((constructor)) init() { + struct sigaction sa; + sa.sa_handler = handler; + sa.sa_flags = SA_RESETHAND; + + sigaction(SIGABRT, &sa, 0); + sigaction(SIGFPE, &sa, 0); + sigaction(SIGINT, &sa, 0); + sigaction(SIGSEGV, &sa, 0); +} Copied: sandbox/trunk/src/nix/btmalloc/btmalloclite.c (from rev 1063, sandbox/trunk/src/nix/btmalloc/btmalloc.c) =================================================================== --- sandbox/trunk/src/nix/btmalloc/btmalloclite.c (rev 0) +++ sandbox/trunk/src/nix/btmalloc/btmalloclite.c 2009-05-25 18:31:33 UTC (rev 1433) @@ -0,0 +1,29 @@ +#define _GNU_SOURCE +#include <stdio.h> +#include <dlfcn.h> +#include <execinfo.h> +#include <pthread.h> + +#define MAX_FRAMES 20 + +void * +malloc(size_t sz) +{ + // Find and cache the next malloc (in our example it should be the "real" + // malloc). + static void * (*func)(); + if (!func) + func = (void *(*)()) dlsym(RTLD_NEXT, "malloc"); + + void *p = func(sz); + + if (!p) { + printf("Th%lu malloc(%zu) failed!\n", pthread_self(), sz); + + void* array[MAX_FRAMES]; + size_t size = backtrace(array, sizeof(array)/sizeof(*array)); + backtrace_symbols_fd(array, size, 1); + } + + return p; +} Modified: sandbox/trunk/src/nix/btmalloc/run.bash =================================================================== --- sandbox/trunk/src/nix/btmalloc/run.bash 2009-05-25 18:26:32 UTC (rev 1432) +++ sandbox/trunk/src/nix/btmalloc/run.bash 2009-05-25 18:31:33 UTC (rev 1433) @@ -1,3 +1,9 @@ +#!/usr/bin/env bash + +set -o errexit -o nounset + g++ -Wall -g3 -o test test.cc -gcc -Wall -lbfd -ldl -fPIC -shared -o btmalloc.so btmalloc.c #backtrace.c -LD_PRELOAD=./btmalloc.so ./test +gcc -Wall -lbfd -ldl -fPIC -shared -o btmalloc.so btmalloc.c +gcc -Wall -ldl -lpthread -fPIC -shared -o btmalloclite.so btmalloclite.c +LD_PRELOAD=./btmalloc.so ./test || true +LD_PRELOAD=./btmalloclite.so ./test || true Added: sandbox/trunk/src/nix/btmalloc/symbolize.py =================================================================== --- sandbox/trunk/src/nix/btmalloc/symbolize.py (rev 0) +++ sandbox/trunk/src/nix/btmalloc/symbolize.py 2009-05-25 18:31:33 UTC (rev 1433) @@ -0,0 +1,44 @@ +#!/usr/bin/python +# +# Resolves glibc's backtrace output into file and line numbers using addr2line. +# +# Evan Jones <ev...@mi...> +# March, 2008 + +import os +import re +import sys + +ADDR2LINE = "addr2line" +EXTRACT_ADDR = re.compile(r'\[(0x[0-9a-f]+)\]$') + +binary = sys.argv[1] + +addrs = [] +functions = [] +filelines = [] + +# Extract addresses +for line in sys.stdin: + matchobj = EXTRACT_ADDR.search(line) + if matchobj: + addrs.append(matchobj.group(1)) + +# Feed into addr2line +command = ['addr2line', '--demangle', '--functions', '-e', binary] +command.extend(addrs) + +child_in, child_out = os.popen2(command) +child_in.close() +for line in child_out: + line = line.strip() + if len(functions) == len(filelines): + functions.append(line) + else: + filelines.append(line) +code = child_out.close() +assert code is None + +for fileline in filelines: + if fileline.startswith("??"): continue + print fileline This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |