xref: /titanic_50/usr/src/lib/libast/common/vmalloc/vmtrace.c (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
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