xref: /illumos-gate/usr/src/contrib/ast/src/lib/libast/vmalloc/vmtrace.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
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  
_STUB_vmtrace()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
trstrcpy(char * to,const char * from,int endc)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
tritoa(Vmulong_t v,int type)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
trtrace(Vmalloc_t * vm,Vmuchar_t * oldaddr,Vmuchar_t * newaddr,size_t size,size_t align)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
_vmmessage(const char * s1,long n1,const char * s2,long n2)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
vmtrace(int file)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
vmtrbusy(Vmalloc_t * vm)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