1 | /**************************************** |
---|
2 | * Computer Algebra System SINGULAR * |
---|
3 | ****************************************/ |
---|
4 | /* $Id: mmbt.c,v 1.13 1999-10-22 09:07:03 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 | * 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 6000 |
---|
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 unsigned long 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 >= (unsigned long) &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 (unsigned long *bt_stack) |
---|
66 | { |
---|
67 | unsigned long pc, *fp = getfp ((unsigned long *) &bt_stack); |
---|
68 | int i=0; |
---|
69 | |
---|
70 | if (mm_lowpc==0) mmTrackInit(); |
---|
71 | |
---|
72 | while ((fp!=NULL) && ((unsigned long)fp>4095) |
---|
73 | && ((unsigned long)fp < ((unsigned long)0xf0000000)) |
---|
74 | && *fp && (pc = getpc (fp)) |
---|
75 | && !entrypc (pc) && (i<BT_MAXSTACK)) |
---|
76 | { |
---|
77 | bt_stack[i]=pc; i++; |
---|
78 | fp = (unsigned long *) *fp; |
---|
79 | } |
---|
80 | while(i<BT_MAXSTACK) |
---|
81 | { |
---|
82 | bt_stack[i]=0; i++; |
---|
83 | } |
---|
84 | } |
---|
85 | |
---|
86 | struct |
---|
87 | { |
---|
88 | unsigned long p; |
---|
89 | char *name; |
---|
90 | } p2n[MAX_PROCS_BT]; |
---|
91 | |
---|
92 | extern char* feResource(char what); |
---|
93 | static int mm_p2n_max = -1; |
---|
94 | void mmP2cNameInit() |
---|
95 | { |
---|
96 | FILE *f; |
---|
97 | int i,j; |
---|
98 | char n[128]; |
---|
99 | char s[1000]; |
---|
100 | sprintf(s, "./mprnm -p %s >nm.log", "Singularg"); |
---|
101 | system(s); |
---|
102 | f=fopen("nm.log","r"); |
---|
103 | i=0; |
---|
104 | loop |
---|
105 | { |
---|
106 | j=fscanf(f,"%d %s\n",(int *)&p2n[i].p,n); |
---|
107 | if (j!=2) |
---|
108 | { |
---|
109 | break; |
---|
110 | } |
---|
111 | if (strcmp(n, "___crt_dummy__") != 0 && strcmp(n, "_start") != 0) |
---|
112 | { |
---|
113 | p2n[i].name=strdup(n); |
---|
114 | i++; |
---|
115 | } |
---|
116 | } |
---|
117 | fclose(f); |
---|
118 | // unlink("nm.log"); |
---|
119 | p2n[i].name="??"; |
---|
120 | p2n[i].p=~1; |
---|
121 | mm_p2n_max=i; |
---|
122 | } |
---|
123 | char * mmP2cName(unsigned long p) |
---|
124 | { |
---|
125 | int i, e; |
---|
126 | int a=0; |
---|
127 | if (mm_p2n_max == -1) |
---|
128 | mmP2cNameInit(); |
---|
129 | e=mm_p2n_max; |
---|
130 | loop |
---|
131 | { |
---|
132 | if (a>=e-1) |
---|
133 | { |
---|
134 | if (p2n[a].p<=p) return p2n[a].name; |
---|
135 | else if (a==0) return("??"); |
---|
136 | else Print("?? sort %x,%d in %d and %d\n",p,p,a,e); |
---|
137 | } |
---|
138 | i=(a+e)/2; |
---|
139 | if (p>=p2n[i].p) |
---|
140 | { |
---|
141 | a=i; |
---|
142 | } |
---|
143 | else |
---|
144 | { |
---|
145 | e=i; |
---|
146 | } |
---|
147 | } |
---|
148 | #if 0 |
---|
149 | for(i=0;i<=mm_p2n_max;i++) |
---|
150 | { |
---|
151 | if (p>=p2n[i].p) |
---|
152 | { |
---|
153 | if (p<p2n[i+1].p) return p2n[i].name; |
---|
154 | if (0==p2n[i+1].p) return p2n[i].name; |
---|
155 | } |
---|
156 | } |
---|
157 | return "??"; |
---|
158 | #endif |
---|
159 | } |
---|
160 | |
---|
161 | void mmPrintStack(FILE *fd, unsigned long *stack, int all) |
---|
162 | { |
---|
163 | mmPrintStackFrames(fd, stack, 0, BT_MAXSTACK, all); |
---|
164 | } |
---|
165 | |
---|
166 | void mmDBPrintThisStack(FILE *fd, void* memblock, int all, int free) |
---|
167 | { |
---|
168 | #ifdef MTRACK_FREE |
---|
169 | if (free) |
---|
170 | mmPrintStackFrames(fd, ((DBMCB*) memblock)->bt_freed_stack, 0, BT_MAXSTACK, all); |
---|
171 | else |
---|
172 | #endif |
---|
173 | mmPrintStackFrames(fd, ((DBMCB*) memblock)->bt_allocated_stack, 0, BT_MAXSTACK, all); |
---|
174 | } |
---|
175 | |
---|
176 | void mmDBPrintStack(FILE *fd, void* memblock, int all) |
---|
177 | { |
---|
178 | mmPrintStackFrames(fd, ((DBMCB*) memblock)->bt_allocated_stack, 0, BT_MAXSTACK, all); |
---|
179 | } |
---|
180 | |
---|
181 | void mmDBPrintStackFrames(FILE *fd, void* memblock, int start, int end) |
---|
182 | { |
---|
183 | mmPrintStackFrames(fd, ((DBMCB*) memblock)->bt_allocated_stack, start, end, |
---|
184 | MM_PRINT_ALL_STACK); |
---|
185 | } |
---|
186 | |
---|
187 | /* print stack */ |
---|
188 | void mmPrintStackFrames(FILE *fd, unsigned long *bt_stack, int start, int end, int mm) |
---|
189 | { |
---|
190 | int i=start; |
---|
191 | fprintf( fd," "); |
---|
192 | do |
---|
193 | { |
---|
194 | char *s; |
---|
195 | s=mmP2cName(bt_stack[i]); |
---|
196 | if (s!=NULL && strcmp(s, "??")) |
---|
197 | { |
---|
198 | if ((mm & MM_PRINT_ALL_STACK) || strncmp(s, "mm", 2) !=0) |
---|
199 | fprintf( fd,":%s",s); |
---|
200 | if (strcmp(s, "main") == 0) break; |
---|
201 | } |
---|
202 | else |
---|
203 | fprintf( fd,":%lx",(long)bt_stack[i]); |
---|
204 | i++; |
---|
205 | } while ((i<end) && (bt_stack[i]!=0)); |
---|
206 | fprintf( fd,"\n"); |
---|
207 | } |
---|
208 | #endif /* linux, i386 */ |
---|
209 | #endif /* not optimize */ |
---|
210 | #endif /* MTRACK */ |
---|