/* This here is a tool for chasing down memory leaks. As written it requires that the program be using my PureIO module (pureio.c). This can be changed. By Paul Kienitz 7/90 public domain. */ /* What ya do is put macros in your shit sorta like this #define AllocMem(a, b) AllocYell((long) a, (long) b, __FUNC__, (long) __LINE__) #define FreeMem(a, b) FreeYell(a, (long) b, __FUNC__, (long) __LINE__) void *AllocYell(), FreeYell(); or if you're using Paul.h you should put these in first: #undef FreeMem #define _AllocMem(a, b) AllocYell((long) a, (long) b, __FUNC__, (long) __LINE__) #define _FreeMem(a, b) FreeYell(a, (long) b, __FUNC__, (long) __LINE__) and it'll tell you about all the memory you allocate and free. It'll let you know in what order which calls allocate what. Then you just need some kinda filter to spot mismatches and you're all set. I'll make one out of Uedit. Something like this: Match up allocation/deallocation reports in program output */ #include #include #undef put import /* from pureio.c */ void put(), putfmt(); /* caller must OpenPureIO */ import adr _AllocMem(); import void _FreeMem(); #define MC MEMF_CHIP #define MF MEMF_FAST #define MP MEMF_PUBLIC #define MZ MEMF_CLEAR #define ML MEMF_LARGEST void pause() { long trash; if (IsInteractive(Input()) && Output()) { Write(Output(), "Press RETURN: ", 14L); Read(Input(), &trash, 1L); } } adr AllocYell(s, f, y, l) long s, f; str y; long l; { register adr foo = _AllocMem(s, f); union { long w; char n[4]; } t; short i = 0; t.w = 0; if (f & MC) t.n[i++] = 'C'; if (f & MP) t.n[i++] = 'P'; if (f & MZ) t.n[i++] = 'Z'; if (!i) t.w = 'any\0'; if (foo) putfmt("## Allocated %ld at 0x%lx: ", s, foo); else putfmt("++ FAILED to allocate %ld bytes ", s); putfmt("(%s), in %s line %ld, largest %ld.\n", t.n, y, l, AvailMem(ML)); if (!foo) { putfmt("++ AvailMem reports: CHIP %ld total %ld largest,\n " "FAST %ld total %ld largest.\n", AvailMem(MC), AvailMem(MC | ML), AvailMem(MF), AvailMem(MF | ML)); pause(); } return foo; } void FreeYell(a, s, y, l) adr a; long s; str y; long l; { if (!TypeOfMem(a) || s <= 0 || s >= 500000) { putfmt("++!! BOGUS FREEMEM:\n %ld bytes at " "0x%lx at line %ld in call %s.\n", s, a, l, y); pause(); return; /* DON'T free it! */ } putfmt("%%%% Freed %ld at 0x%lx: in call %s line %ld.\n", s, a, y, l); _FreeMem(a, s); }