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