1 | /**************************************** |
---|
2 | * Computer Algebra System SINGULAR * |
---|
3 | ****************************************/ |
---|
4 | /* $Id: mmbt.c,v 1.22 1999-11-17 12:09:27 obachman 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 | * - nm: to find entry pints if MPRPC is not set |
---|
11 | * files: - feGetResource('S'): the name of the executable |
---|
12 | * - nm.log: temp. file for the map address -> name |
---|
13 | */ |
---|
14 | |
---|
15 | /* for simplicity: a fixed size array (currently used: 4437 entries (98111016)) |
---|
16 | */ |
---|
17 | #define MAX_PROCS_BT 6000 |
---|
18 | |
---|
19 | #include <stdio.h> |
---|
20 | #include <stdlib.h> |
---|
21 | #include <string.h> |
---|
22 | #include <unistd.h> |
---|
23 | #include <signal.h> |
---|
24 | #include <stddef.h> |
---|
25 | #include "mod2.h" |
---|
26 | #include "tok.h" |
---|
27 | #include "mmprivate.h" |
---|
28 | #include "febase.h" |
---|
29 | #include "mmbt.h" |
---|
30 | |
---|
31 | |
---|
32 | #ifdef MTRACK |
---|
33 | // #ifndef __OPTIMIZE__ |
---|
34 | /* does only work in debug mode: |
---|
35 | * requires that -fomit-frame-pointer is not given |
---|
36 | */ |
---|
37 | #if defined(linux) && defined(__i386__) |
---|
38 | |
---|
39 | static unsigned long mm_lowpc=0, mm_highpc=0; |
---|
40 | |
---|
41 | extern int etext (); |
---|
42 | |
---|
43 | /* |
---|
44 | * Number of words between saved pc and saved fp. |
---|
45 | * All stack frames seen by mmTrack() must conform to |
---|
46 | * the same value of SLOP. |
---|
47 | */ |
---|
48 | #ifndef SLOP |
---|
49 | #define SLOP 0 |
---|
50 | #endif |
---|
51 | |
---|
52 | #define entrypc(pc) ((pc >= mm_lowpc && pc <= mm_highpc) || pc >= (unsigned long) &etext || (pc < 4096)) |
---|
53 | #define getfp(ap) (ap-2-SLOP) |
---|
54 | #define getpc(fp) (fp[1+SLOP]) |
---|
55 | |
---|
56 | int mmTrackInit () |
---|
57 | { |
---|
58 | char *entry = getenv ("MPRPC"); |
---|
59 | |
---|
60 | if ((entry!=NULL) && (strchr (entry, ':')!=NULL)) |
---|
61 | { |
---|
62 | mm_lowpc = atoi (entry); |
---|
63 | mm_highpc = atoi (1 + strchr (entry, ':')); |
---|
64 | return 0; |
---|
65 | } |
---|
66 | else if (feRes_works) |
---|
67 | { |
---|
68 | char buf[255]; |
---|
69 | sprintf(buf,"nm -n %s",feGetResource('S')); |
---|
70 | { |
---|
71 | FILE *nm=popen(buf,"r"); |
---|
72 | if (nm==NULL) |
---|
73 | { |
---|
74 | fprintf(stderr, |
---|
75 | "environment variable MPRPC not found\nand pipe to `%s`failed\n",buf); |
---|
76 | m2_end(1); |
---|
77 | } |
---|
78 | else |
---|
79 | { |
---|
80 | while(fgets(buf,sizeof(buf),nm)) |
---|
81 | { |
---|
82 | if((strstr(buf," t ")!=NULL) |
---|
83 | ||(strstr(buf," T ")!=NULL)) |
---|
84 | { |
---|
85 | if(strstr(buf," _start\n")!=NULL) |
---|
86 | { |
---|
87 | sscanf(buf,"%lx",&mm_lowpc); |
---|
88 | fgets(buf,sizeof(buf),nm); |
---|
89 | sscanf(buf,"%lx",&mm_highpc); |
---|
90 | mm_highpc--; |
---|
91 | break; |
---|
92 | } |
---|
93 | } |
---|
94 | } |
---|
95 | pclose(nm); |
---|
96 | } |
---|
97 | return 0; |
---|
98 | } |
---|
99 | } |
---|
100 | return 1; |
---|
101 | } |
---|
102 | |
---|
103 | static mmTrack_sig11_caught = 0; |
---|
104 | typedef void (*si_hdl_typ)(int); |
---|
105 | |
---|
106 | void mmTrack_sig11_handler(int sig) |
---|
107 | { |
---|
108 | mmTrack_sig11_caught = 1; |
---|
109 | printf("SIG11 Caught\n"); |
---|
110 | fflush(stdout); |
---|
111 | } |
---|
112 | |
---|
113 | int mm_no_mtrack = 0; |
---|
114 | |
---|
115 | void mmTrack (unsigned long *bt_stack) |
---|
116 | { |
---|
117 | unsigned long pc, *fp = getfp ((unsigned long *) &bt_stack); |
---|
118 | int i=0; |
---|
119 | #if 0 /* Geht nicht */ |
---|
120 | si_hdl_typ sig11_handler = signal(SIGSEGV, (si_hdl_typ) mmTrack_sig11_handler); |
---|
121 | mmTrack_sig11_caught = 0; |
---|
122 | #endif |
---|
123 | |
---|
124 | if (mm_lowpc==0) mmTrackInit(); |
---|
125 | |
---|
126 | if (! mm_no_mtrack) |
---|
127 | { |
---|
128 | while ((fp!=NULL) && ((unsigned long)fp>4095) |
---|
129 | && ((unsigned long)fp < ((unsigned long)0xff000000)) |
---|
130 | && *fp && (pc = getpc (fp)) |
---|
131 | && !entrypc (pc) && (i<BT_MAXSTACK)) |
---|
132 | { |
---|
133 | if ( mmTrack_sig11_caught) break; |
---|
134 | bt_stack[i]=pc; i++; |
---|
135 | fp = (unsigned long *) *fp; |
---|
136 | } |
---|
137 | } |
---|
138 | /* signal(SIGSEGV, (si_hdl_typ) sig11_handler); */ |
---|
139 | while(i<BT_MAXSTACK) |
---|
140 | { |
---|
141 | bt_stack[i]=0; i++; |
---|
142 | } |
---|
143 | } |
---|
144 | |
---|
145 | struct |
---|
146 | { |
---|
147 | unsigned long p; |
---|
148 | char *name; |
---|
149 | } p2n[MAX_PROCS_BT]; |
---|
150 | |
---|
151 | static int mm_p2n_max = -1; |
---|
152 | void mmP2cNameInit() |
---|
153 | { |
---|
154 | FILE *f; |
---|
155 | int i,j; |
---|
156 | char n[128]; |
---|
157 | char s[2000]; |
---|
158 | sprintf(s, "%s/mprnm -mprdem %s/mprdem -p %s >nm.log", |
---|
159 | feGetResource('b'), feGetResource('b'), feGetResource('S')); |
---|
160 | system(s); |
---|
161 | f=fopen("nm.log","r"); |
---|
162 | i=0; |
---|
163 | loop |
---|
164 | { |
---|
165 | j=fscanf(f,"%d %s\n",(int *)&p2n[i].p,n); |
---|
166 | if (j!=2) |
---|
167 | { |
---|
168 | break; |
---|
169 | } |
---|
170 | if (strcmp(n, "___crt_dummy__") != 0 && strcmp(n, "_start") != 0) |
---|
171 | { |
---|
172 | p2n[i].name=strdup(n); |
---|
173 | i++; |
---|
174 | } |
---|
175 | } |
---|
176 | fclose(f); |
---|
177 | unlink("nm.log"); |
---|
178 | p2n[i].name="??"; |
---|
179 | p2n[i].p=~1; |
---|
180 | mm_p2n_max=i; |
---|
181 | } |
---|
182 | |
---|
183 | char * mmP2cName(unsigned long p) |
---|
184 | { |
---|
185 | int i, e; |
---|
186 | int a=0; |
---|
187 | if (mm_p2n_max == -1) |
---|
188 | mmP2cNameInit(); |
---|
189 | e=mm_p2n_max; |
---|
190 | loop |
---|
191 | { |
---|
192 | if (a>=e-1) |
---|
193 | { |
---|
194 | if (p2n[a].p<=p) return p2n[a].name; |
---|
195 | else if (a==0) return("??"); |
---|
196 | else Print("?? sort %x,%d in %d and %d\n",p,p,a,e); |
---|
197 | } |
---|
198 | i=(a+e)/2; |
---|
199 | if (p>=p2n[i].p) |
---|
200 | { |
---|
201 | a=i; |
---|
202 | } |
---|
203 | else |
---|
204 | { |
---|
205 | e=i; |
---|
206 | } |
---|
207 | } |
---|
208 | #if 0 |
---|
209 | for(i=0;i<=mm_p2n_max;i++) |
---|
210 | { |
---|
211 | if (p>=p2n[i].p) |
---|
212 | { |
---|
213 | if (p<p2n[i+1].p) return p2n[i].name; |
---|
214 | if (0==p2n[i+1].p) return p2n[i].name; |
---|
215 | } |
---|
216 | } |
---|
217 | return "??"; |
---|
218 | #endif |
---|
219 | } |
---|
220 | |
---|
221 | void mmPrintStack(FILE *fd, unsigned long *stack, int all) |
---|
222 | { |
---|
223 | mmPrintStackFrames(fd, stack, 0, BT_MAXSTACK, all); |
---|
224 | } |
---|
225 | |
---|
226 | void mmDBPrintThisStack(FILE *fd, void* memblock, int all, int free) |
---|
227 | { |
---|
228 | #ifdef MTRACK_FREE |
---|
229 | if (free) |
---|
230 | mmPrintStackFrames(fd, ((DBMCB*) memblock)->bt_freed_stack, 0, BT_MAXSTACK, all); |
---|
231 | else |
---|
232 | #endif |
---|
233 | mmPrintStackFrames(fd, ((DBMCB*) memblock)->bt_allocated_stack, 0, BT_MAXSTACK, all); |
---|
234 | } |
---|
235 | |
---|
236 | void mmDBPrintStack(FILE *fd, void* memblock, int all) |
---|
237 | { |
---|
238 | mmPrintStackFrames(fd, ((DBMCB*) memblock)->bt_allocated_stack, 0, BT_MAXSTACK, all); |
---|
239 | } |
---|
240 | |
---|
241 | void mmDBPrintStackFrames(FILE *fd, void* memblock, int start, int end) |
---|
242 | { |
---|
243 | mmPrintStackFrames(fd, ((DBMCB*) memblock)->bt_allocated_stack, start, end, |
---|
244 | MM_PRINT_ALL_STACK); |
---|
245 | } |
---|
246 | |
---|
247 | /* print stack */ |
---|
248 | void mmPrintStackFrames(FILE *fd, unsigned long *bt_stack, int start, int end, int mm) |
---|
249 | { |
---|
250 | int i=start; |
---|
251 | fprintf( fd," "); |
---|
252 | do |
---|
253 | { |
---|
254 | char *s; |
---|
255 | s=mmP2cName(bt_stack[i]); |
---|
256 | if (s!=NULL && strcmp(s, "??")) |
---|
257 | { |
---|
258 | if ((mm & MM_PRINT_ALL_STACK) || strncmp(s, "mm", 2) !=0) |
---|
259 | fprintf( fd,":%s",s); |
---|
260 | if (strcmp(s, "main") == 0) break; |
---|
261 | } |
---|
262 | else |
---|
263 | fprintf( fd,":%lx",(long)bt_stack[i]); |
---|
264 | i++; |
---|
265 | } while ((i<end) && (bt_stack[i]!=0)); |
---|
266 | fprintf( fd,"\n"); |
---|
267 | } |
---|
268 | #endif /* linux, i386 */ |
---|
269 | // #endif /* not optimize */ |
---|
270 | #endif /* MTRACK */ |
---|