13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* More debugging hooks for `malloc'.
23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o   Copyright (C) 1991, 1992 Free Software Foundation, Inc.
33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 Written April 2, 1991 by John Gilmore of Cygnus Support.
43839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		 Based on mcheck.c by Mike Haertel.
53839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
63839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oThis library is free software; you can redistribute it and/or
73839e65723771b85975f4263102dd3ceec4523cTheodore Ts'omodify it under the terms of the GNU Library General Public License as
83839e65723771b85975f4263102dd3ceec4523cTheodore Ts'opublished by the Free Software Foundation; either version 2 of the
93839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oLicense, or (at your option) any later version.
103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oThis library is distributed in the hope that it will be useful,
123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'obut WITHOUT ANY WARRANTY; without even the implied warranty of
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oLibrary General Public License for more details.
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oYou should have received a copy of the GNU Library General Public
173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oLicense along with this library; see the file COPYING.LIB.  If
183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'onot, write to the Free Software Foundation, Inc., 675 Mass Ave,
193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oCambridge, MA 02139, USA.
203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o   The author may be reached (Email) at the address mike@ai.mit.edu,
223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o   or (US mail) as Mike Haertel c/o Free Software Foundation.  */
233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#ifndef	_MALLOC_INTERNAL
253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#define	_MALLOC_INTERNAL
26c59a704b79cbb9e35050d4555b149b780149069dTheodore Ts'o#include "./mtrace.h"
273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#endif
283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#ifndef	__GNU_LIBRARY__
323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oextern char *getenv ();
333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#else
343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdlib.h>
353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#endif
363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic FILE *mallstream;
383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic char mallenv[]= "MALLOC_TRACE";
393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic char mallbuf[BUFSIZ];	/* Buffer for the output.  */
403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* Address to breakpoint on accesses to... */
423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o__ptr_t mallwatch;
433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* Old hook values.  */
453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void (*tr_old_free_hook) __P ((__ptr_t ptr));
463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic __ptr_t (*tr_old_malloc_hook) __P ((size_t size));
473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr, size_t size));
483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
50efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * Added by TYT, 10/10/93 --- so that we can print
513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oFILE *malloc_get_mallstream()
533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return mallstream;
553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* This function is called when the block being alloc'd, realloc'd, or
583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o   freed has an address matching the variable "mallwatch".  In a debugger,
593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o   set "mallwatch" to the address of interest, then put a breakpoint on
603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o   tr_break.  */
613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid tr_break __P ((void));
633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid
643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'otr_break ()
653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void tr_freehook __P ((__ptr_t));
693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void
703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'otr_freehook (ptr)
713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o     __ptr_t ptr;
723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  fprintf (mallstream, "- %p\n", ptr);	/* Be sure to print it first.  */
743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  if (ptr == mallwatch)
753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    tr_break ();
763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __free_hook = tr_old_free_hook;
773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  free (ptr);
783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __free_hook = tr_freehook;
793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic __ptr_t tr_mallochook __P ((size_t));
823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic __ptr_t
833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'otr_mallochook (size)
843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o     size_t size;
853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __ptr_t hdr;
873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __malloc_hook = tr_old_malloc_hook;
893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  hdr = (__ptr_t) malloc (size);
903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __malloc_hook = tr_mallochook;
913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  /* We could be printing a NULL here; that's OK.  */
933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  fprintf (mallstream, "+ %p %d\n", hdr, size);
943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  if (hdr == mallwatch)
963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    tr_break ();
973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  return hdr;
993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic __ptr_t tr_reallochook __P ((__ptr_t, size_t));
1023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic __ptr_t
1033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'otr_reallochook (ptr, size)
1043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o     __ptr_t ptr;
1053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o     size_t size;
1063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __ptr_t hdr;
1083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  if (ptr == mallwatch)
1103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    tr_break ();
1113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __free_hook = tr_old_free_hook;
1133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __malloc_hook = tr_old_malloc_hook;
1143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __realloc_hook = tr_old_realloc_hook;
1153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  hdr = (__ptr_t) realloc (ptr, size);
1163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __free_hook = tr_freehook;
1173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __malloc_hook = tr_mallochook;
1183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  __realloc_hook = tr_reallochook;
1193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  if (hdr == NULL)
1203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    /* Failed realloc.  */
1213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    fprintf (mallstream, "! %p %d\n", ptr, size);
1223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  else
1233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    fprintf (mallstream, "< %p\n> %p %d\n", ptr, hdr, size);
1243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  if (hdr == mallwatch)
1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    tr_break ();
1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  return hdr;
1293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* We enable tracing if either the environment variable MALLOC_TRACE
1323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o   is set, or if the variable mallwatch has been patched to an address
1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o   that the debugging user wants us to stop on.  When patching mallwatch,
1343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o   don't forget to set a breakpoint on tr_break!  */
1353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid
1373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'omtrace ()
1383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  char *mallfile;
1403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  mallfile = getenv (mallenv);
1423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o  if (mallfile != NULL || mallwatch != NULL)
1433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    {
1443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o      mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "w");
1453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o      if (mallstream != NULL)
1463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	{
1473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	  /* Be sure it doesn't malloc its buffer!  */
1483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	  setbuf (mallstream, mallbuf);
1493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	  fprintf (mallstream, "= Start\n");
1503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	  tr_old_free_hook = __free_hook;
1513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	  __free_hook = tr_freehook;
1523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	  tr_old_malloc_hook = __malloc_hook;
1533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	  __malloc_hook = tr_mallochook;
1543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	  tr_old_realloc_hook = __realloc_hook;
1553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	  __realloc_hook = tr_reallochook;
1563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o    }
1583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
159