da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Method to help with debugging. This does rigorous checks on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** addresses and arena integrity.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* structure to keep track of file names */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* global watch list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* types of warnings reported by dbwarn() */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int Dbfd = 2; /* default warning file descriptor */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* just an entry point to make it easy to set break point */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* issue a warning of some type */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void dbwarn(Vmalloc_t* vm, Void_t* data, int where,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char* file, int line, const Void_t* func, int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void dbwarn(vm, data, where, file, line, func, type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* region info */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(vm), 0), ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp,(*_Vmitoa)(VLONG(data),0),':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else bufp = (*_Vmstrcpy)(bufp, "region is locked", ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(DBSIZE(data),-1), ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(LONGV(where),-1), ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((s = DBFILE(data)) && (bufp + strlen(s) + SLOP) < endbuf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp,(*_Vmitoa)(LONGV(DBLINE(data)),-1),':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* location where offending call originates from */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(file && file[0] && line > 0 && (bufp + strlen(file) + SLOP) < endbuf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(LONGV(line),-1), ',');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(func),-1), ':');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* check for watched address and issue warnings */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char* file, int line, const Void_t* func, int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst char* file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n = Dbnwatch; n >= 0; --n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* record information about the block */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void dbsetinfo(Vmuchar_t* data, size_t size, const char* file, int line)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmuchar_t* data; /* real address not the one from Vmbest */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst char* file; /* file where the request came from */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* find the file structure */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { for(last = NIL(Dbfile_t*), db = Dbfile; db; last = db, db = db->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { db = (Dbfile_t*)vmalloc(Vmheap,sizeof(Dbfile_t)+strlen(file));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Check to see if an address is in some data block of a region.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** This returns -(offset+1) if block is already freed, +(offset+1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** if block is live, 0 if no match.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1L;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(local) /* must be vmfree or vmresize checking address */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(b < endb)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((Vmuchar_t*)addr >= data && (Vmuchar_t*)addr < data+SIZE(b))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1L;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(b < endb)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { dbwarn(vm,NIL(Vmuchar_t*),0,file,line,func,DB_ALLOC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(s < sizeof(Body_t)) /* no tiny blocks during Vmdebug */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = sizeof(Body_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(data = (Vmuchar_t*)KPVALLOC(vm,s,(*(Vmbest->allocf))) ) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { dbwarn(vm,NIL(Vmuchar_t*),DB_ALLOC,file,line,func,DB_ALLOC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner { dbwarn(vm,(Vmuchar_t*)data,offset == -1L ? 0 : 1,file,line,func,DB_FREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*_Vmtrace)(vm,(Vmuchar_t*)data,NIL(Vmuchar_t*),DBSIZE(data),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* clear free space */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rv = KPVFREE((vm), (Void_t*)DB2BEST(data), (*Vmbest->freef));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Resizing an existing block */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* dbresize(Vmalloc_t* vm, Void_t* addr, reg size_t size, int type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { dbwarn(vm,NIL(Vmuchar_t*),0,file,line,func,DB_RESIZE);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner { dbwarn(vm,(Vmuchar_t*)addr,offset == -1L ? 0 : 1,file,line,func,DB_RESIZE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)(*vm->disc->exceptf)(vm,VM_BADADDR,addr,vm->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Vmbest data block */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* do the resize */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(s < sizeof(Body_t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = sizeof(Body_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { dbwarn(vm,NIL(Vmuchar_t*),DB_ALLOC,file,line,func,DB_RESIZE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do { *d++ = 0; } while(d < ed);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* compact any residual free space */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* check for memory overwrites over all live blocks */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check the meta-data of this region */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(b < endb)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next: b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* set/delete an address to watch */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n < 0) /* insert */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* delete left-most */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n = 0; n < Dbnwatch; ++n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* dbalign(Vmalloc_t* vm, size_t size, size_t align)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((s = ROUND(size,ALIGN) + DB_EXTRA) < sizeof(Body_t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = sizeof(Body_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(data = (Vmuchar_t*)KPVALIGN(vm,s,align,(*(Vmbest->alignf)))) )
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner/* print statistics of region vm. If vm is NULL, use Vmregion */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)((Vmulong_t)st.n_busy,-1), ',');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, " s_busy", '=');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.s_busy),-1), '\n');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)((Vmulong_t)st.n_free,-1), ',');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, " s_free", '=');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.s_free),-1), '\n');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.m_busy),-1), ',');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, " m_free", '=');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.m_free),-1), '\n');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, "n_segment", '=');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)((Vmulong_t)st.n_seg,-1), ',');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, " extent", '=');
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.extent),-1), '\n');