1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #if defined(_UWIN) && defined(_BLD_ast)
23
_STUB_vmtrace()24 void _STUB_vmtrace(){}
25
26 #else
27
28 #include "vmhdr.h"
29
30 /* Turn on tracing for regions
31 **
32 ** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
33 */
34
35 static int Trfile = -1;
36 static char Trbuf[128];
37
38 #if __STD_C
trstrcpy(char * to,const char * from,int endc)39 static char* trstrcpy(char* to, const char* from, int endc)
40 #else
41 static char* trstrcpy(to, from, endc)
42 char* to;
43 const char* from;
44 int endc;
45 #endif
46 { reg int n;
47
48 n = strlen(from);
49 memcpy(to,from,n);
50 to += n;
51 if((*to = endc) )
52 to += 1;
53 return to;
54 }
55
56 /* convert a long value to an ascii representation */
57 #if __STD_C
tritoa(Vmulong_t v,int type)58 static char* tritoa(Vmulong_t v, int type)
59 #else
60 static char* tritoa(v, type)
61 Vmulong_t v; /* value to convert */
62 int type; /* =0 base-16, >0: unsigned base-10, <0: signed base-10 */
63 #endif
64 {
65 char* s;
66
67 s = &Trbuf[sizeof(Trbuf) - 1];
68 *s-- = '\0';
69
70 if(type == 0) /* base-16 */
71 { reg char* digit = "0123456789abcdef";
72 do
73 { *s-- = digit[v&0xf];
74 v >>= 4;
75 } while(v);
76 }
77 else if(type > 0) /* unsigned base-10 */
78 { do
79 { *s-- = (char)('0' + (v%10));
80 v /= 10;
81 } while(v);
82 }
83 else /* signed base-10 */
84 { int sign = ((long)v < 0);
85 if(sign)
86 v = (Vmulong_t)(-((long)v));
87 do
88 { *s-- = (char)('0' + (v%10));
89 v /= 10;
90 } while(v);
91 if(sign)
92 *s-- = '-';
93 }
94
95 return s+1;
96 }
97
98 /* generate a trace of some call */
99 #if __STD_C
trtrace(Vmalloc_t * vm,Vmuchar_t * oldaddr,Vmuchar_t * newaddr,size_t size,size_t align)100 static void trtrace(Vmalloc_t* vm,
101 Vmuchar_t* oldaddr, Vmuchar_t* newaddr, size_t size, size_t align )
102 #else
103 static void trtrace(vm, oldaddr, newaddr, size, align)
104 Vmalloc_t* vm; /* region call was made from */
105 Vmuchar_t* oldaddr; /* old data address */
106 Vmuchar_t* newaddr; /* new data address */
107 size_t size; /* size of piece */
108 size_t align; /* alignment */
109 #endif
110 {
111 char buf[1024], *bufp, *endbuf;
112 Vmdata_t* vd = vm->data;
113 const char* file = 0;
114 int line = 0;
115 const Void_t* func = 0;
116 int comma;
117 int n;
118 int m;
119
120 int type;
121 #define SLOP 64
122
123 if(oldaddr == (Vmuchar_t*)(-1)) /* printing busy blocks */
124 { type = 0;
125 oldaddr = NIL(Vmuchar_t*);
126 }
127 else
128 { type = vd->mode&VM_METHODS;
129 VMFLF(vm,file,line,func);
130 }
131
132 if(Trfile < 0)
133 return;
134
135 bufp = buf; endbuf = buf+sizeof(buf);
136 bufp = trstrcpy(bufp, tritoa(oldaddr ? VLONG(oldaddr) : 0L, 0), ':');
137 bufp = trstrcpy(bufp, tritoa(newaddr ? VLONG(newaddr) : 0L, 0), ':');
138 bufp = trstrcpy(bufp, tritoa((Vmulong_t)size, 1), ':');
139 bufp = trstrcpy(bufp, tritoa((Vmulong_t)align, 1), ':');
140 bufp = trstrcpy(bufp, tritoa(VLONG(vm), 0), ':');
141 if(type&VM_MTBEST)
142 bufp = trstrcpy(bufp, "b", ':');
143 else if(type&VM_MTLAST)
144 bufp = trstrcpy(bufp, "l", ':');
145 else if(type&VM_MTPOOL)
146 bufp = trstrcpy(bufp, "p", ':');
147 else if(type&VM_MTPROFILE)
148 bufp = trstrcpy(bufp, "s", ':');
149 else if(type&VM_MTDEBUG)
150 bufp = trstrcpy(bufp, "d", ':');
151 else bufp = trstrcpy(bufp, "u", ':');
152
153 comma = 0;
154 if(file && file[0] && line > 0)
155 { if((bufp + strlen(file) + SLOP) >= endbuf)
156 { char* f;
157 for(f = bufp + strlen(file); f > file; --f)
158 if(f[-1] == '/' || f[-1] == '\\')
159 break;
160 file = f;
161 }
162
163 bufp = trstrcpy(bufp, "file", '=');
164 n = endbuf - bufp - SLOP - 3;
165 m = strlen(file);
166 if(m > n)
167 { file += (m - n);
168 bufp = trstrcpy(bufp, "..", '.');
169 }
170 bufp = trstrcpy(bufp, file, ',');
171 bufp = trstrcpy(bufp, "line", '=');
172 bufp = trstrcpy(bufp, tritoa((Vmulong_t)line,1), 0);
173 comma = 1;
174 }
175 if(func)
176 { if(comma)
177 *bufp++ = ',';
178 bufp = trstrcpy(bufp, "func", '=');
179 #if _PACKAGE_ast
180 bufp = trstrcpy(bufp, (const char*)func, 0);
181 #else
182 bufp = trstrcpy(bufp, tritoa((Vmulong_t)func,0), 0);
183 #endif
184 comma = 1;
185 }
186 if(comma)
187 *bufp++ = ':';
188
189 *bufp++ = '\n';
190 *bufp = '\0';
191
192 write(Trfile,buf,(bufp-buf));
193 }
194
195 #if DEBUG
196 #if __STD_C
_vmmessage(const char * s1,long n1,const char * s2,long n2)197 void _vmmessage(const char* s1, long n1, const char* s2, long n2)
198 #else
199 void _vmmessage(s1, n1, s2, n2)
200 const char* s1;
201 long n1;
202 const char* s2;
203 long n2;
204 #endif
205 {
206 char buf[1024], *bufp;
207
208 bufp = buf;
209 bufp = trstrcpy(bufp, "vmalloc", ':');
210 if (s1)
211 {
212 bufp = trstrcpy(bufp, s1, ':');
213 if (n1)
214 bufp = trstrcpy(bufp, tritoa(n1, 1), ':');
215 }
216 if (s2)
217 {
218 bufp = trstrcpy(bufp, s2, ':');
219 if (n2)
220 bufp = trstrcpy(bufp, tritoa(n2, 0), ':');
221 }
222 bufp = trstrcpy(bufp, tritoa((long)getpid(), 1), ':');
223 *bufp++ = '\n';
224 write(2,buf,(bufp-buf));
225 }
226 #endif
227
228 #if __STD_C
vmtrace(int file)229 int vmtrace(int file)
230 #else
231 int vmtrace(file)
232 int file;
233 #endif
234 {
235 int fd;
236
237 _Vmstrcpy = trstrcpy;
238 _Vmitoa = tritoa;
239 _Vmtrace = trtrace;
240
241 fd = Trfile;
242 Trfile = file;
243 return fd;
244 }
245
246 #if __STD_C
vmtrbusy(Vmalloc_t * vm)247 int vmtrbusy(Vmalloc_t* vm)
248 #else
249 int vmtrbusy(vm)
250 Vmalloc_t* vm;
251 #endif
252 {
253 Seg_t* seg;
254 Vmdata_t* vd = vm->data;
255
256 if(Trfile < 0 || !(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE)))
257 return -1;
258
259 for(seg = vd->seg; seg; seg = seg->next)
260 { Block_t *b, *endb;
261 Vmuchar_t* data;
262 size_t s;
263
264 for(b = SEGBLOCK(seg), endb = BLOCK(seg->baddr); b < endb; )
265 { if(ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b)))
266 continue;
267
268 data = DATA(b);
269 if(vd->mode&VM_MTDEBUG)
270 { data = DB2DEBUG(data);
271 s = DBSIZE(data);
272 }
273 else if(vd->mode&VM_MTPROFILE)
274 s = PFSIZE(data);
275 else s = SIZE(b)&~BITS;
276
277 trtrace(vm, (Vmuchar_t*)(-1), data, s, 0);
278
279 b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
280 }
281 }
282
283 return 0;
284 }
285
286 #endif
287