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