xref: /onnv-gate/usr/src/lib/libast/common/vmalloc/vmtrace.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #if defined(_UWIN) && defined(_BLD_ast)
234887Schin 
_STUB_vmtrace()244887Schin void _STUB_vmtrace(){}
254887Schin 
264887Schin #else
274887Schin 
284887Schin #include	"vmhdr.h"
294887Schin 
304887Schin /*	Turn on tracing for regions
314887Schin **
324887Schin **	Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
334887Schin */
344887Schin 
354887Schin static int	Trfile = -1;
364887Schin static char	Trbuf[128];
374887Schin 
384887Schin #if __STD_C
trstrcpy(char * to,const char * from,int endc)394887Schin static char* trstrcpy(char* to, const char* from, int endc)
404887Schin #else
414887Schin static char* trstrcpy(to, from, endc)
424887Schin char*		to;
434887Schin const char*	from;
444887Schin int		endc;
454887Schin #endif
464887Schin {	reg int	n;
474887Schin 
484887Schin 	n = strlen(from);
494887Schin 	memcpy(to,from,n);
504887Schin 	to += n;
514887Schin 	if((*to = endc) )
524887Schin 		to += 1;
534887Schin 	return to;
544887Schin }
554887Schin 
564887Schin /* convert a long value to an ascii representation */
574887Schin #if __STD_C
tritoa(Vmulong_t v,int type)584887Schin static char* tritoa(Vmulong_t v, int type)
594887Schin #else
604887Schin static char* tritoa(v, type)
614887Schin Vmulong_t	v;	/* value to convert					*/
624887Schin int		type;	/* =0 base-16, >0: unsigned base-10, <0: signed base-10	*/
634887Schin #endif
644887Schin {
654887Schin 	char*	s;
664887Schin 
674887Schin 	s = &Trbuf[sizeof(Trbuf) - 1];
684887Schin 	*s-- = '\0';
694887Schin 
704887Schin 	if(type == 0)		/* base-16 */
714887Schin 	{	reg char*	digit = "0123456789abcdef";
724887Schin 		do
734887Schin 		{	*s-- = digit[v&0xf];
744887Schin 			v >>= 4;
754887Schin 		} while(v);
764887Schin 	}
774887Schin 	else if(type > 0)	/* unsigned base-10 */
784887Schin 	{	do
794887Schin 		{	*s-- = (char)('0' + (v%10));
804887Schin 			v /= 10;
814887Schin 		} while(v);
824887Schin 	}
834887Schin 	else			/* signed base-10 */
844887Schin 	{	int	sign = ((long)v < 0);
854887Schin 		if(sign)
864887Schin 			v = (Vmulong_t)(-((long)v));
874887Schin 		do
884887Schin 		{	*s-- = (char)('0' + (v%10));
894887Schin 			v /= 10;
904887Schin 		} while(v);
914887Schin 		if(sign)
924887Schin 			*s-- = '-';
934887Schin 	}
944887Schin 
954887Schin 	return s+1;
964887Schin }
974887Schin 
984887Schin /* generate a trace of some call */
994887Schin #if __STD_C
trtrace(Vmalloc_t * vm,Vmuchar_t * oldaddr,Vmuchar_t * newaddr,size_t size,size_t align)1004887Schin static void trtrace(Vmalloc_t* vm,
1014887Schin 		    Vmuchar_t* oldaddr, Vmuchar_t* newaddr, size_t size, size_t align )
1024887Schin #else
1034887Schin static void trtrace(vm, oldaddr, newaddr, size, align)
1044887Schin Vmalloc_t*	vm;		/* region call was made from	*/
1054887Schin Vmuchar_t*	oldaddr;	/* old data address		*/
1064887Schin Vmuchar_t*	newaddr;	/* new data address		*/
1074887Schin size_t		size;		/* size of piece		*/
1084887Schin size_t		align;		/* alignment			*/
1094887Schin #endif
1104887Schin {
1114887Schin 	char		buf[1024], *bufp, *endbuf;
1124887Schin 	Vmdata_t*	vd = vm->data;
1134887Schin 	const char*	file = 0;
1144887Schin 	int		line = 0;
1154887Schin 	const Void_t*	func = 0;
1164887Schin 	int		comma;
1174887Schin 	int		n;
1184887Schin 	int		m;
1194887Schin 
1204887Schin 	int		type;
1214887Schin #define SLOP	64
1224887Schin 
1234887Schin 	if(oldaddr == (Vmuchar_t*)(-1)) /* printing busy blocks */
1244887Schin 	{	type = 0;
1254887Schin 		oldaddr = NIL(Vmuchar_t*);
1264887Schin 	}
1274887Schin 	else
1284887Schin 	{	type = vd->mode&VM_METHODS;
1294887Schin 		VMFLF(vm,file,line,func);
1304887Schin 	}
1314887Schin 
1324887Schin 	if(Trfile < 0)
1334887Schin 		return;
1344887Schin 
1354887Schin 	bufp = buf; endbuf = buf+sizeof(buf);
1364887Schin 	bufp = trstrcpy(bufp, tritoa(oldaddr ? VLONG(oldaddr) : 0L, 0), ':');
1374887Schin 	bufp = trstrcpy(bufp, tritoa(newaddr ? VLONG(newaddr) : 0L, 0), ':');
1384887Schin 	bufp = trstrcpy(bufp, tritoa((Vmulong_t)size, 1), ':');
1394887Schin 	bufp = trstrcpy(bufp, tritoa((Vmulong_t)align, 1), ':');
1404887Schin 	bufp = trstrcpy(bufp, tritoa(VLONG(vm), 0), ':');
1414887Schin 	if(type&VM_MTBEST)
1424887Schin 		bufp = trstrcpy(bufp, "b", ':');
1434887Schin 	else if(type&VM_MTLAST)
1444887Schin 		bufp = trstrcpy(bufp, "l", ':');
1454887Schin 	else if(type&VM_MTPOOL)
1464887Schin 		bufp = trstrcpy(bufp, "p", ':');
1474887Schin 	else if(type&VM_MTPROFILE)
1484887Schin 		bufp = trstrcpy(bufp, "s", ':');
1494887Schin 	else if(type&VM_MTDEBUG)
1504887Schin 		bufp = trstrcpy(bufp, "d", ':');
1514887Schin 	else	bufp = trstrcpy(bufp, "u", ':');
1524887Schin 
1534887Schin 	comma = 0;
1544887Schin 	if(file && file[0] && line > 0)
1554887Schin 	{	if((bufp + strlen(file) + SLOP) >= endbuf)
1564887Schin 		{	char*	f;
1574887Schin 			for(f = bufp + strlen(file); f > file; --f)
1584887Schin 				if(f[-1] == '/' || f[-1] == '\\')
1594887Schin 					break;
1604887Schin 			file = f;
1614887Schin 		}
1624887Schin 
1634887Schin 		bufp = trstrcpy(bufp, "file", '=');
1644887Schin 		n = endbuf - bufp - SLOP - 3;
1654887Schin 		m = strlen(file);
1664887Schin 		if(m > n)
1674887Schin 		{	file += (m - n);
1684887Schin 			bufp = trstrcpy(bufp, "..", '.');
1694887Schin 		}
1704887Schin 		bufp = trstrcpy(bufp, file, ',');
1714887Schin 		bufp = trstrcpy(bufp, "line", '=');
1724887Schin 		bufp = trstrcpy(bufp, tritoa((Vmulong_t)line,1), 0);
1734887Schin 		comma = 1;
1744887Schin 	}
1754887Schin 	if(func)
1764887Schin 	{	if(comma)
1774887Schin 			*bufp++ = ',';
1784887Schin 		bufp = trstrcpy(bufp, "func", '=');
1794887Schin #if _PACKAGE_ast
1804887Schin 		bufp = trstrcpy(bufp, (const char*)func, 0);
1814887Schin #else
1824887Schin 		bufp = trstrcpy(bufp, tritoa((Vmulong_t)func,0), 0);
1834887Schin #endif
1844887Schin 		comma = 1;
1854887Schin 	}
1864887Schin 	if(comma)
1874887Schin 		*bufp++ = ':';
1884887Schin 
1894887Schin 	*bufp++ = '\n';
1904887Schin 	*bufp = '\0';
1914887Schin 
1924887Schin 	write(Trfile,buf,(bufp-buf));
1934887Schin }
1944887Schin 
1954887Schin #if DEBUG
1964887Schin #if __STD_C
_vmmessage(const char * s1,long n1,const char * s2,long n2)1974887Schin void _vmmessage(const char* s1, long n1, const char* s2, long n2)
1984887Schin #else
1994887Schin void _vmmessage(s1, n1, s2, n2)
2004887Schin const char*	s1;
2014887Schin long		n1;
2024887Schin const char*	s2;
2034887Schin long		n2;
2044887Schin #endif
2054887Schin {
2064887Schin 	char	buf[1024], *bufp;
2074887Schin 
2084887Schin 	bufp = buf;
2094887Schin 	bufp = trstrcpy(bufp, "vmalloc", ':');
2104887Schin 	if (s1)
2114887Schin 	{
2124887Schin 		bufp = trstrcpy(bufp, s1, ':');
2134887Schin 		if (n1)
2144887Schin 			bufp = trstrcpy(bufp, tritoa(n1, 1), ':');
2154887Schin 	}
2164887Schin 	if (s2)
2174887Schin 	{
2184887Schin 		bufp = trstrcpy(bufp, s2, ':');
2194887Schin 		if (n2)
2204887Schin 			bufp = trstrcpy(bufp, tritoa(n2, 0), ':');
2214887Schin 	}
222*12068SRoger.Faulkner@Oracle.COM 	bufp = trstrcpy(bufp, tritoa((long)getpid(), 1), ':');
2234887Schin 	*bufp++ = '\n';
2244887Schin 	write(2,buf,(bufp-buf));
2254887Schin }
2264887Schin #endif
2274887Schin 
2284887Schin #if __STD_C
vmtrace(int file)2294887Schin int vmtrace(int file)
2304887Schin #else
2314887Schin int vmtrace(file)
2324887Schin int	file;
2334887Schin #endif
2344887Schin {
2354887Schin 	int	fd;
2364887Schin 
2374887Schin 	_Vmstrcpy = trstrcpy;
2384887Schin 	_Vmitoa = tritoa;
2394887Schin 	_Vmtrace = trtrace;
2404887Schin 
2414887Schin 	fd = Trfile;
2424887Schin 	Trfile = file;
2434887Schin 	return fd;
2444887Schin }
2454887Schin 
2464887Schin #if __STD_C
vmtrbusy(Vmalloc_t * vm)2474887Schin int vmtrbusy(Vmalloc_t* vm)
2484887Schin #else
2494887Schin int vmtrbusy(vm)
2504887Schin Vmalloc_t*	vm;
2514887Schin #endif
2524887Schin {
2534887Schin 	Seg_t*		seg;
2544887Schin 	Vmdata_t*	vd = vm->data;
2554887Schin 
2564887Schin 	if(Trfile < 0 || !(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE)))
2574887Schin 		return -1;
2584887Schin 
2594887Schin 	for(seg = vd->seg; seg; seg = seg->next)
2604887Schin 	{	Block_t		*b, *endb;
2614887Schin 		Vmuchar_t*	data;
2624887Schin 		size_t		s;
2634887Schin 
2644887Schin 		for(b = SEGBLOCK(seg), endb = BLOCK(seg->baddr); b < endb; )
2654887Schin 		{	if(ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b)))
2664887Schin 				continue;
2674887Schin 
2684887Schin 			data = DATA(b);
2694887Schin 			if(vd->mode&VM_MTDEBUG)
2704887Schin 			{	data = DB2DEBUG(data);
2714887Schin 				s = DBSIZE(data);
2724887Schin 			}
2734887Schin 			else if(vd->mode&VM_MTPROFILE)
2744887Schin 				s = PFSIZE(data);
2754887Schin 			else	s = SIZE(b)&~BITS;
2764887Schin 
2774887Schin 			trtrace(vm, (Vmuchar_t*)(-1), data, s, 0);
2784887Schin 
2794887Schin 			b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
2804887Schin 		}
2814887Schin 	}
2824887Schin 
2834887Schin 	return 0;
2844887Schin }
2854887Schin 
2864887Schin #endif
287