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 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 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 196 void _vmmessage(const char* s1, long n1, const char* s2, long n2) 197 #else 198 void _vmmessage(s1, n1, s2, n2) 199 const char* s1; 200 long n1; 201 const char* s2; 202 long 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 229 int vmtrace(int file) 230 #else 231 int vmtrace(file) 232 int 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 247 int vmtrbusy(Vmalloc_t* vm) 248 #else 249 int vmtrbusy(vm) 250 Vmalloc_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