/**************************************** * Computer Algebra System SINGULAR * ****************************************/ /* $Id: mmbt.c,v 1.8 1999-03-19 17:42:28 obachman Exp $ */ /* * ABSTRACT: backtrace: part of memory subsystem (for linux/elf) * needed programs: - mprpc to set the variable MPRPC * - mprdem: must be in the current directory * - mprnm: must be in thje current directory * files: - Singularg: the name of the executable * - nm.log: temp. file for the map address -> name */ /* for simplicity: a fixed size array (currently used: 4437 entries (98111016)) */ #define MAX_PROCS_BT 5000 #include #include #include #include #include "mod2.h" #include "tok.h" #include "mmprivate.h" #include "febase.h" #include "mmbt.h" #ifdef MTRACK #ifndef __OPTIMIZE__ /* does only work in debug mode: * requires that -fomit-frame-pointer is not given */ #if defined(linux) && defined(__i386__) static unsigned long mm_lowpc=0, mm_highpc=0; extern int etext (); /* * Number of words between saved pc and saved fp. * All stack frames seen by mmTrack() must conform to * the same value of SLOP. */ #ifndef SLOP #define SLOP 0 #endif #define entrypc(pc) ((pc >= mm_lowpc && pc <= mm_highpc) || pc >= (unsigned long) &etext || (pc < 4096)) #define getfp(ap) (ap-2-SLOP) #define getpc(fp) (fp[1+SLOP]) int mmTrackInit () { char *entry = getenv ("MPRPC"); if ((entry!=NULL) && (strchr (entry, ':')!=NULL)) { mm_lowpc = atoi (entry); mm_highpc = atoi (1 + strchr (entry, ':')); return 0; } return 1; } void mmTrack (unsigned long *bt_stack) { unsigned long pc, *fp = getfp ((unsigned long *) &bt_stack); int i=0; if (mm_lowpc==0) mmTrackInit(); while ((fp!=NULL) && ((unsigned long)fp>4095) && *fp && (pc = getpc (fp)) && !entrypc (pc) && (inm.log"); f=fopen("nm.log","r"); i=0; loop { j=fscanf(f,"%d %s\n",(int *)&p2n[i].p,n); if (j!=2) break; if (strcmp(n, "___crt_dummy__") != 0 && strcmp(n, "_start") != 0) { p2n[i].name=strdup(n); i++; } } fclose(f); unlink("nm.log"); p2n[i].name="??"; p2n[i].p=~1; mm_p2n_max=i; } char * mmP2cName(unsigned long p) { int i, e; int a=0; if (mm_p2n_max == -1) mmP2cNameInit(); e=mm_p2n_max; loop { if (a>=e-1) { if (p2n[a].p<=p) return p2n[a].name; else if (a==0) return("??"); else Print("?? sort %x,%d in %d and %d\n",p,p,a,e); } i=(a+e)/2; if (p>=p2n[i].p) { a=i; } else { e=i; } } #if 0 for(i=0;i<=mm_p2n_max;i++) { if (p>=p2n[i].p) { if (pbt_stack, 0, BT_MAXSTACK, all); } void mmDBPrintStackFrames(void* memblock, int start, int end) { mmPrintStackFrames(((DBMCB*) memblock)->bt_stack, start, end, MM_PRINT_ALL_STACK); } /* print stack */ void mmPrintStackFrames(unsigned long *bt_stack, int start, int end, int mm) { int i=start; PrintS(" "); do { char *s; s=mmP2cName(bt_stack[i]); if (s!=NULL) { if ((mm & MM_PRINT_ALL_STACK) || strncmp(s, "mm", 2) !=0) fprintf( stderr,":%s",s); if (strcmp(s, "main") == 0) break; } else fprintf( stderr,":%x",bt_stack[i]); i++; } while ((i