1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1985-2011 AT&T Intellectual Property * 5* and is licensed under the * 6* Eclipse Public License, Version 1.0 * 7* by AT&T Intellectual Property * 8* * 9* A copy of the License is available at * 10* http://www.eclipse.org/org/documents/epl-v10.html * 11* (with md5 checksum b35adb5213ca9657e911e9befb180842) * 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 24void _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 35static int Trfile = -1; 36static char Trbuf[128]; 37 38#if __STD_C 39static char* trstrcpy(char* to, const char* from, int endc) 40#else 41static char* trstrcpy(to, from, endc) 42char* to; 43const char* from; 44int 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 58static char* tritoa(Vmulong_t v, int type) 59#else 60static char* tritoa(v, type) 61Vmulong_t v; /* value to convert */ 62int 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 100static void trtrace(Vmalloc_t* vm, 101 Vmuchar_t* oldaddr, Vmuchar_t* newaddr, size_t size, size_t align ) 102#else 103static void trtrace(vm, oldaddr, newaddr, size, align) 104Vmalloc_t* vm; /* region call was made from */ 105Vmuchar_t* oldaddr; /* old data address */ 106Vmuchar_t* newaddr; /* new data address */ 107size_t size; /* size of piece */ 108size_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 char* 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 1 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 __STD_C 196void _vmmessage(const char* s1, long n1, const char* s2, long n2) 197#else 198void _vmmessage(s1, n1, s2, n2) 199const char* s1; 200long n1; 201const char* s2; 202long n2; 203#endif 204{ 205 char buf[1024], *bufp; 206 207 bufp = buf; 208 bufp = trstrcpy(bufp, "vmalloc", ':'); 209 if (s1) 210 { 211 bufp = trstrcpy(bufp, s1, ':'); 212 if (n1) 213 bufp = trstrcpy(bufp, tritoa(n1, 1), ':'); 214 } 215 if (s2) 216 { 217 bufp = trstrcpy(bufp, s2, ':'); 218 if (n2) 219 bufp = trstrcpy(bufp, tritoa(n2, 0), ':'); 220 } 221 222 bufp = trstrcpy(bufp, tritoa((long)getpid(), 1), ':'); 223 224 *bufp++ = '\n'; 225 write(2,buf,(bufp-buf)); 226} 227 228#if __STD_C 229int vmtrace(int file) 230#else 231int vmtrace(file) 232int 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 247int vmtrbusy(Vmalloc_t* vm) 248#else 249int vmtrbusy(vm) 250Vmalloc_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