[comp.lang.c] Some help with malloc pointer problems

geoff@tolerant.com (Geoffrey Leach) (05/05/90)

Here's a useful little hack to help you track down that nasty little
malloc pointer problem.  If it seems over-elaborate, it might help
to know that my problem was with an X application.  X toolkits
malloc like there was no tomorrow.

What follows is a shar file.  Cut at the line and feed to /bin/sh
------------------------------------------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README_TRACK malloc_track.c track_report.c
# Wrapped by geoff@yasc on Fri May  4 09:02:13 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README_TRACK' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README_TRACK'\"
else
echo shar: Extracting \"'README_TRACK'\" \(2013 characters\)
sed "s/^X//" >'README_TRACK' <<'END_OF_FILE'
XHere's a useful little hack to help you track down that nasty little
Xmalloc pointer problem.  If this seems over-elaborate, it might help
Xto know that my problem was with an X application.  X toolkits
Xmalloc like there was no tomorrow.
X
XYou can use this without source to malloc by doing a little creative
Xre-naming, but its easier if you have malloc source.  A couple of 
Xgood debugging mallocs have been posted to the net recently.
X
XHere's how malloc_track works.
X
XPatch your malloc, free and realloc routines in the appropriate places
Xwith calls to malloc_track.  The first argument will be -1, -2, ...
Xaccording to how the tags array in track_report is set up.  Mine is set
Xup with two points for realloc, because of the way the one I was working 
Xwith was set up.
X
XYou need a special value (-5 here) for flagging the track value for
Xtrack_report.
X
XOnce you've set up your library routines, you patch your code in appropriate
Xplaces with calls to malloc_track.  The first argument is a non-negative
Xinteger that marks where you're tracking, the second is the value that gets
Xput in the report.  To just report position, use 0.
X
XNow you're ready to go.  At an appropriate point in your program's execution,
Xset malloc_track_enable to 1.  This opens the file in your cwd and starts
Xthe writing of <tag, value> integer pairs.  When you know what the pointer
Xaddress that is causing you problems is, assign this value to
Xmalloc_track_target.  Malloc track will report to you every time it sees 
Xthis address and also provides you with a convenient place to set a breakpoint.
X
XIn order to see what happens, you run track_report.  As arguments, you
Xuse tags for the places where you put calls to malloc_track in your own
Xcode.  The result is a little report with all of the tracked activity.
XWhen the address you specified in malloc_track_target appears, its
Xspecially marked.
X
XHope this helps.  Happy debugging.
X
XGeoffrey Leach
XTolerant Software
Xgeoff@tolerant.com  or ... {pyramid | apply | amhdal}!tolsoft!geoff
END_OF_FILE
if test 2013 -ne `wc -c <'README_TRACK'`; then
    echo shar: \"'README_TRACK'\" unpacked with wrong size!
fi
# end of 'README_TRACK'
fi
if test -f 'malloc_track.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'malloc_track.c'\"
else
echo shar: Extracting \"'malloc_track.c'\" \(747 characters\)
sed "s/^X//" >'malloc_track.c' <<'END_OF_FILE'
X#include <sys/fcntl.h>
X
Xstatic int	trackFD;
Xstatic int	malloc_track_target_noticed;
Xint		malloc_track_enable;
Xchar	       *malloc_track_target  =(char *) -1;
Xstatic int	track_target_init = -5;
X
Xvoid
Xmalloc_track(n, v)
X	int	n;
X	char   *v;
X{
X	if (!malloc_track_enable)
X		return;
X
X	if (trackFD == 0) 
X		trackFD = open("malloc_track", O_RDWR | O_CREAT, 0644);
X	if (!malloc_track_target_noticed && (malloc_track_target != (char *) -1)){
X		malloc_track_target_noticed = 1;
X		write(trackFD, &track_target_init, sizeof(int));
X		write(trackFD, &malloc_track_target, sizeof(char *));
X	}
X	write(trackFD, &n, sizeof(int));
X	write(trackFD, &v, sizeof(char *));
X	if (v == malloc_track_target)
X		write(2, "track target event\n", 19); /* set breakpoint here */
X}
END_OF_FILE
if test 747 -ne `wc -c <'malloc_track.c'`; then
    echo shar: \"'malloc_track.c'\" unpacked with wrong size!
fi
# end of 'malloc_track.c'
fi
if test -f 'track_report.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'track_report.c'\"
else
echo shar: Extracting \"'track_report.c'\" \(864 characters\)
sed "s/^X//" >'track_report.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <sys/fcntl.h>
X
Xchar *tags[] = {"", "malloc", "free", "realloc request", "realloc result", 
X		"target"};
X
Xmain(argc, argv)
X	int   argc;
X	char *argv[];
X{
X	int   fd;
X	int   n;
X	char  *target;
X	char  *a;
X	char  *l;
X	char  *tag;
X	char   buf[30];
X
X	fd = open("malloc_track", O_RDONLY);
X	while (read(fd, &n, sizeof(int))) {
X		read(fd, &a, sizeof(char *));
X		if (n < 0) {
X			if (n == -5) {
X				target = a;
X				continue;
X			}
X			if (a == target)
X				printf("0x%x - %-8s\t<----\n", a, tags[-n]);
X			else
X				printf("0x%x - %s\n", a, tags[-n]);
X		}
X		else {
X			if ((n+1) < argc)
X				tag = argv[n+1];
X			else {
X				sprintf(buf, "watchpoint %d", n);
X				tag = buf;
X			}
X			if (a > 0) {
X				if (a == target)
X					printf("0x%x - %-8s\t<----\n", a, tag);
X				else
X					printf("0x%x - %s\n", a, tag);
X			}
X			else
X				printf("\t - %s\n", tag);
X		}
X	}
X}
END_OF_FILE
if test 864 -ne `wc -c <'track_report.c'`; then
    echo shar: \"'track_report.c'\" unpacked with wrong size!
fi
# end of 'track_report.c'
fi
echo shar: End of shell archive.
exit 0