1 | /**************************************** |
---|
2 | * Computer Algebra System SINGULAR * |
---|
3 | ****************************************/ |
---|
4 | /* $Id: mmbt.c,v 1.6 1999-03-18 17:00:15 Singular Exp $ */ |
---|
5 | /* |
---|
6 | * ABSTRACT: backtrace: part of memory subsystem (for linux/elf) |
---|
7 | * needed programs: - mprpc to set the variable MPRPC |
---|
8 | * - mprdem: must be in the current directory |
---|
9 | * - mprnm: must be in thje current directory |
---|
10 | * files: - Singularg: the name of the executable |
---|
11 | * - nm.log: temp. file for the map address -> name |
---|
12 | */ |
---|
13 | |
---|
14 | /* for simplicity: a fixed size array (currently used: 4437 entries (98111016)) |
---|
15 | */ |
---|
16 | #define MAX_PROCS_BT 5000 |
---|
17 | |
---|
18 | #include <stdio.h> |
---|
19 | #include <stdlib.h> |
---|
20 | #include <string.h> |
---|
21 | #include <unistd.h> |
---|
22 | #include "mod2.h" |
---|
23 | #include "tok.h" |
---|
24 | #include "mmprivate.h" |
---|
25 | #include "febase.h" |
---|
26 | #include "mmbt.h" |
---|
27 | |
---|
28 | #ifdef MTRACK |
---|
29 | #ifndef __OPTIMIZE__ |
---|
30 | /* does only work in debug mode: |
---|
31 | * requires that -fomit-frame-pointer is not given |
---|
32 | */ |
---|
33 | #if defined(linux) && defined(__i386__) |
---|
34 | |
---|
35 | static ulong mm_lowpc=0, mm_highpc=0; |
---|
36 | |
---|
37 | extern int etext (); |
---|
38 | |
---|
39 | /* |
---|
40 | * Number of words between saved pc and saved fp. |
---|
41 | * All stack frames seen by mmTrack() must conform to |
---|
42 | * the same value of SLOP. |
---|
43 | */ |
---|
44 | #ifndef SLOP |
---|
45 | #define SLOP 0 |
---|
46 | #endif |
---|
47 | |
---|
48 | #define entrypc(pc) ((pc >= mm_lowpc && pc <= mm_highpc) || pc >= (ulong) &etext || (pc < 4096)) |
---|
49 | #define getfp(ap) (ap-2-SLOP) |
---|
50 | #define getpc(fp) (fp[1+SLOP]) |
---|
51 | |
---|
52 | int mmTrackInit () |
---|
53 | { |
---|
54 | char *entry = getenv ("MPRPC"); |
---|
55 | |
---|
56 | if ((entry!=NULL) && (strchr (entry, ':')!=NULL)) |
---|
57 | { |
---|
58 | mm_lowpc = atoi (entry); |
---|
59 | mm_highpc = atoi (1 + strchr (entry, ':')); |
---|
60 | return 0; |
---|
61 | } |
---|
62 | return 1; |
---|
63 | } |
---|
64 | |
---|
65 | void mmTrack (ulong *bt_stack) |
---|
66 | { |
---|
67 | ulong pc, *fp = getfp ((ulong *) &bt_stack); |
---|
68 | int i=0; |
---|
69 | |
---|
70 | if (mm_lowpc==0) mmTrackInit(); |
---|
71 | |
---|
72 | while ((fp!=NULL) && ((ulong)fp>4095) && *fp && (pc = getpc (fp)) |
---|
73 | && !entrypc (pc) && (i<BT_MAXSTACK)) |
---|
74 | { |
---|
75 | bt_stack[i]=pc; i++; |
---|
76 | fp = (ulong *) *fp; |
---|
77 | } |
---|
78 | while(i<BT_MAXSTACK) |
---|
79 | { |
---|
80 | bt_stack[i]=0; i++; |
---|
81 | } |
---|
82 | } |
---|
83 | |
---|
84 | struct |
---|
85 | { |
---|
86 | ulong p; |
---|
87 | char *name; |
---|
88 | } p2n[MAX_PROCS_BT]; |
---|
89 | |
---|
90 | static int mm_p2n_max; |
---|
91 | void mmP2cNameInit() |
---|
92 | { |
---|
93 | FILE *f; |
---|
94 | int i,j; |
---|
95 | char n[128]; |
---|
96 | system("./mprnm -p Singularg >nm.log"); |
---|
97 | f=fopen("nm.log","r"); |
---|
98 | i=0; |
---|
99 | loop |
---|
100 | { |
---|
101 | j=fscanf(f,"%d %s\n",(int *)&p2n[i].p,n); |
---|
102 | if (j!=2) break; |
---|
103 | p2n[i].name=strdup(n); |
---|
104 | i++; |
---|
105 | } |
---|
106 | fclose(f); |
---|
107 | unlink("nm.log"); |
---|
108 | p2n[i].name="??"; |
---|
109 | p2n[i].p=~1; |
---|
110 | mm_p2n_max=i; |
---|
111 | } |
---|
112 | char * mmP2cName(ulong p) |
---|
113 | { |
---|
114 | int a=0; |
---|
115 | int e=mm_p2n_max; |
---|
116 | int i; |
---|
117 | loop |
---|
118 | { |
---|
119 | if (a>=e-1) |
---|
120 | { |
---|
121 | if (p2n[a].p<=p) return p2n[a].name; |
---|
122 | else if (a==0) return("??"); |
---|
123 | else Print("?? sort %x,%d in %d and %d\n",p,p,a,e); |
---|
124 | } |
---|
125 | i=(a+e)/2; |
---|
126 | if (p>=p2n[i].p) |
---|
127 | { |
---|
128 | a=i; |
---|
129 | } |
---|
130 | else |
---|
131 | { |
---|
132 | e=i; |
---|
133 | } |
---|
134 | } |
---|
135 | #if 0 |
---|
136 | for(i=0;i<=mm_p2n_max;i++) |
---|
137 | { |
---|
138 | if (p>=p2n[i].p) |
---|
139 | { |
---|
140 | if (p<p2n[i+1].p) return p2n[i].name; |
---|
141 | if (0==p2n[i+1].p) return p2n[i].name; |
---|
142 | } |
---|
143 | } |
---|
144 | return "??"; |
---|
145 | #endif |
---|
146 | } |
---|
147 | |
---|
148 | void mmPrintStack(ulong *bt_stack) /* print stack */ |
---|
149 | { |
---|
150 | int i=0; |
---|
151 | do |
---|
152 | { |
---|
153 | Print(":%x(%s)",bt_stack[i],mmP2cName(bt_stack[i])); |
---|
154 | i++; |
---|
155 | } while ((i<BT_MAXSTACK) && (bt_stack[i]!=0)); |
---|
156 | PrintLn(); |
---|
157 | } |
---|
158 | #endif /* linux, i386 */ |
---|
159 | #endif /* not optimize */ |
---|
160 | #endif /* MTRACK */ |
---|