[Xbubble-commits] xbubble-sdl/src backtrace.c,NONE,1.1
Martin Quinson
mquinson at alioth.debian.org
Mon Sep 11 19:54:48 UTC 2006
- Previous message: [Xbubble-commits] xbubble-sdl/src Makefile.am, 1.1.1.1,
1.2 Makefile.in, 1.1.1.1, 1.2 board.c, 1.1.1.1, 1.2 board.h,
1.1.1.1, 1.2 bubble.c, 1.1.1.1, 1.2 cell.c, 1.1.1.1,
1.2 cell.h, 1.1.1.1, 1.2 config.h.in, 1.1.1.1, 1.2 path_init.c,
1.1.1.1, 1.2 setting.h, 1.1.1.1, 1.2 utils.h, 1.1.1.1,
1.2 xbubble.c, 1.1.1.1, 1.2
- Next message: [Xbubble-commits] xbubble-sdl/src board.c, 1.2, 1.3 board.h, 1.2,
1.3 bubble.c, 1.2, 1.3 bubble.h, 1.1.1.1, 1.2 cell.c, 1.2,
1.3 cell.h, 1.2, 1.3 frame.c, 1.1.1.1, 1.2 path_init.c, 1.2,
1.3 setting.h, 1.2, 1.3 theme.c, 1.1.1.1, 1.2 xbubble.c, 1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/xbubble/xbubble-sdl/src
In directory haydn:/tmp/cvs-serv8858
Added Files:
backtrace.c
Log Message:
Current state. Still not working
--- NEW FILE: backtrace.c ---
/* $Id: backtrace.c,v 1.1 2006/09/11 19:54:45 mquinson Exp $ */
/* Backtrace displaying (neat on debugging) */
/* ex - Exception Handling (modified to fit into SimGrid from OSSP version) */
/* Copyright (c) 2005-2006 Martin Quinson */
/* All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
/* Add this to your configure.ac:
AC_CHECK_HEADERS(execinfo.h)
AC_CHECK_FUNCS(popen)
AC_PATH_PROG(ADDR2LINE, addr2line)
if test x$ADDR2LINE != x ; then
AC_DEFINE_UNQUOTED(ADDR2LINE,"$ADDR2LINE",[Path to the addr2line tool])
fi
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h> /* getpid() */
#include <unistd.h>
#include "config.h" /* where the result of autoconf lives */
#include "utils.h" /* where my prototype lives */
#ifdef HAVE_EXECINFO_H
# include <execinfo.h>
#endif
#define MAX_BACKTRACE_SIZE 30
char *binary_name; /* Should be set from argv by main */
void display_backtrace() {
#if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE)
void *bt[MAX_BACKTRACE_SIZE];
int used=backtrace((void**)bt,MAX_BACKTRACE_SIZE);
char **bt_strings=NULL;
int i;
/* to get the backtrace from the libc */
char **the_backtrace = backtrace_symbols (bt, used);
/* To build the commandline of addr2line */
char *cmd = xmalloc(sizeof(char) * (strlen(ADDR2LINE)+strlen(binary_name)+20*used));
char *curr=cmd;
/* to extract the addresses from the backtrace */
char **addrs=xmalloc(sizeof(char*)*used);
char buff[256];
/* To read the output of addr2line */
FILE *pipe_cmd;
char line_func[1024],line_pos[1024];
/* size (in char) of pointers on this arch */
int addr_len=0;
/* Some arches only have stubs of backtrace, no implementation (hppa comes to mind) */
if (!used)
return;
/* build the commandline */
curr += sprintf(curr,"%s -f -e %s ", ADDR2LINE, binary_name);
for (i=0; i<used;i++) {
char *p;
/* retrieve this address */
snprintf(buff,256,"%s",strchr(the_backtrace[i],'[')+1);
p=strchr(buff,']');
*p='\0';
addrs[i]=strdup(buff);
/* Add it to the command line args */
curr+=sprintf(curr,"%s ",addrs[i]);
}
addr_len = strlen(addrs[0]);
/* parse the output and build a new backtrace */
bt_strings = xmalloc(sizeof(char*) * used);
pipe_cmd = popen(cmd, "r");
if (!pipe_cmd) {
fail("Cannot fork addr2line to display the backtrace");
}
for (i=0; i<used; i++) {
fgets(line_func,1024,pipe_cmd);
line_func[strlen(line_func)-1]='\0';
fgets(line_pos,1024,pipe_cmd);
line_pos[strlen(line_pos)-1]='\0';
if (strcmp("??",line_func)) {
bt_strings[i] = xmalloc(256);
sprintf(bt_strings[i], "** In %s() at %s (static symbol)", line_func,line_pos);
} else {
/* Damn. The symbol is in a dynamic library. Let's get wild */
char *maps_name;
FILE *maps;
char maps_buff[512];
long int addr,offset=0;
char *p,*p2;
char *subcmd;
FILE *subpipe;
int found=0;
/* let's look for the offset of this library in our addressing space */
maps_name=xmalloc(256);
sprintf(maps_name,"/proc/%d/maps",(int)getpid());
maps=fopen(maps_name,"r");
sscanf(addrs[i],"%lx",&addr);
sprintf(maps_buff,"%#lx",addr);
if (strcmp(addrs[i],maps_buff)) {
warn("Cannot parse backtrace address '%s' (addr=%#lx)",
addrs[i], addr);
}
//DEBUG("addr=%s (as string) =%#lx (as number)",addrs[i],addr);
while (!found) {
long int first, last;
if (fgets(maps_buff,512,maps) == NULL)
break;
if (i==0) {
maps_buff[strlen(maps_buff) -1]='\0';
//DEBUG("map line: %s", maps_buff);
}
sscanf(maps_buff,"%lx",&first);
p=strchr(maps_buff,'-')+1;
sscanf(p,"%lx",&last);
if (first < addr && addr < last) {
offset = first;
found=1;
}
//DEBUG("%#lx %s [%#lx-%#lx]", addr, found? "in":"out of",first,last);
}
fclose(maps);
free(maps_name);
if (!found) {
warn("Problem while reading the maps file. Following backtrace will be mangled.");
bt_strings[i] = strdup(the_backtrace[i]);
continue;
}
/* Ok, Found the offset of the maps line containing the searched symbol.
We now need to substract this from the address we got from backtrace.
*/
free(addrs[i]);
addrs[i] = xmalloc(256);
sprintf(addrs[i],"0x%0*lx",addr_len-2,addr-offset);
//DEBUG("offset=%#lx new addr=%s",offset,addrs[i]);
/* Got it. We have our new address. Let's get the library path and we are set */
p = strdup(the_backtrace[i]);
p2 = strrchr(p,'(');
if (p2) *p2= '\0';
p2 = strrchr(p,' ');
if (p2) *p2= '\0';
/* Here we go, fire an addr2line up */
subcmd = xmalloc(256);
sprintf(subcmd,"%s -f -e %s %s",ADDR2LINE,p, addrs[i]);
free(p);
//DEBUG("Fire a new command: '%s'",subcmd);
subpipe = popen(subcmd,"r");
if (!subpipe)
fail("Cannot fork addr2line to display the backtrace");
fgets(line_func,1024,subpipe);
line_func[strlen(line_func)-1]='\0';
fgets(line_pos,1024,subpipe);
line_pos[strlen(line_pos)-1]='\0';
pclose(subpipe);
free(subcmd);
/* check whether the trick worked */
if (strcmp("??",line_func)) {
bt_strings[i] = xmalloc(512);
sprintf(bt_strings[i],"** In %s() at %s (dynamic symbol)", line_func,line_pos);
} else {
/* damn, nothing to do here. Let's print the raw address */
bt_strings[i] = xmalloc(512);
sprintf(bt_strings[i],"** In ?? (%s)", the_backtrace[i]);
}
}
free(addrs[i]);
}
pclose(pipe_cmd);
free(addrs);
free(the_backtrace);
free(cmd);
for (i=0; i<used; i++) /* no need to display "display_backtrace" so start at 1 */
fprintf(stderr,"%s\n",bt_strings[i]);
#else
fprintf(stderr,"No backtrace on this arch\n");
#endif
}
- Previous message: [Xbubble-commits] xbubble-sdl/src Makefile.am, 1.1.1.1,
1.2 Makefile.in, 1.1.1.1, 1.2 board.c, 1.1.1.1, 1.2 board.h,
1.1.1.1, 1.2 bubble.c, 1.1.1.1, 1.2 cell.c, 1.1.1.1,
1.2 cell.h, 1.1.1.1, 1.2 config.h.in, 1.1.1.1, 1.2 path_init.c,
1.1.1.1, 1.2 setting.h, 1.1.1.1, 1.2 utils.h, 1.1.1.1,
1.2 xbubble.c, 1.1.1.1, 1.2
- Next message: [Xbubble-commits] xbubble-sdl/src board.c, 1.2, 1.3 board.h, 1.2,
1.3 bubble.c, 1.2, 1.3 bubble.h, 1.1.1.1, 1.2 cell.c, 1.2,
1.3 cell.h, 1.2, 1.3 frame.c, 1.1.1.1, 1.2 path_init.c, 1.2,
1.3 setting.h, 1.2, 1.3 theme.c, 1.1.1.1, 1.2 xbubble.c, 1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Xbubble-commits
mailing list