1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2009 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 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 24 void _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 35 static int Trfile = -1; 36 static char Trbuf[128]; 37 38 #if __STD_C 39 static char* trstrcpy(char* to, const char* from, int endc) 40 #else 41 static char* trstrcpy(to, from, endc) 42 char* to; 43 const char* from; 44 int 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 58 static char* tritoa(Vmulong_t v, int type) 59 #else 60 static char* tritoa(v, type) 61 Vmulong_t v; /* value to convert */ 62 int 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 100 static void trtrace(Vmalloc_t* vm, 101 Vmuchar_t* oldaddr, Vmuchar_t* newaddr, size_t size, size_t align ) 102 #else 103 static void trtrace(vm, oldaddr, newaddr, size, align) 104 Vmalloc_t* vm; /* region call was made from */ 105 Vmuchar_t* oldaddr; /* old data address */ 106 Vmuchar_t* newaddr; /* new data address */ 107 size_t size; /* size of piece */ 108 size_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 Void_t* 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 _PACKAGE_ast 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 DEBUG 196 #if __STD_C 197 void _vmmessage(const char* s1, long n1, const char* s2, long n2) 198 #else 199 void _vmmessage(s1, n1, s2, n2) 200 const char* s1; 201 long n1; 202 const char* s2; 203 long n2; 204 #endif 205 { 206 char buf[1024], *bufp; 207 208 bufp = buf; 209 bufp = trstrcpy(bufp, "vmalloc", ':'); 210 if (s1) 211 { 212 bufp = trstrcpy(bufp, s1, ':'); 213 if (n1) 214 bufp = trstrcpy(bufp, tritoa(n1, 1), ':'); 215 } 216 if (s2) 217 { 218 bufp = trstrcpy(bufp, s2, ':'); 219 if (n2) 220 bufp = trstrcpy(bufp, tritoa(n2, 0), ':'); 221 } 222 *bufp++ = '\n'; 223 write(2,buf,(bufp-buf)); 224 } 225 #endif 226 227 #if __STD_C 228 int vmtrace(int file) 229 #else 230 int vmtrace(file) 231 int file; 232 #endif 233 { 234 int fd; 235 236 _Vmstrcpy = trstrcpy; 237 _Vmitoa = tritoa; 238 _Vmtrace = trtrace; 239 240 fd = Trfile; 241 Trfile = file; 242 return fd; 243 } 244 245 #if __STD_C 246 int vmtrbusy(Vmalloc_t* vm) 247 #else 248 int vmtrbusy(vm) 249 Vmalloc_t* vm; 250 #endif 251 { 252 Seg_t* seg; 253 Vmdata_t* vd = vm->data; 254 255 if(Trfile < 0 || !(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE))) 256 return -1; 257 258 for(seg = vd->seg; seg; seg = seg->next) 259 { Block_t *b, *endb; 260 Vmuchar_t* data; 261 size_t s; 262 263 for(b = SEGBLOCK(seg), endb = BLOCK(seg->baddr); b < endb; ) 264 { if(ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b))) 265 continue; 266 267 data = DATA(b); 268 if(vd->mode&VM_MTDEBUG) 269 { data = DB2DEBUG(data); 270 s = DBSIZE(data); 271 } 272 else if(vd->mode&VM_MTPROFILE) 273 s = PFSIZE(data); 274 else s = SIZE(b)&~BITS; 275 276 trtrace(vm, (Vmuchar_t*)(-1), data, s, 0); 277 278 b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) ); 279 } 280 } 281 282 return 0; 283 } 284 285 #endif 286