home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 1 / GoldFishApril1994_CD2.img / d4xx / d429 / dr / source / leak.c < prev    next >
C/C++ Source or Header  |  1991-01-10  |  4KB  |  155 lines

  1. /* This here is a tool for chasing down memory leaks.  As written it requires
  2. that the program be using my PureIO module (pureio.c).  This can be changed.
  3. By Paul Kienitz 7/90 public domain.
  4. */
  5.  
  6. /* What ya do is put macros in your shit sorta like this
  7.  
  8. #define AllocMem(a, b) AllocYell((long) a, (long) b, __FUNC__, (long) __LINE__)
  9. #define FreeMem(a, b) FreeYell(a, (long) b, __FUNC__, (long) __LINE__)
  10. void *AllocYell(), FreeYell();
  11.  
  12.    or if you're using Paul.h you should put these in first:
  13.  
  14. #undef FreeMem
  15. #define _AllocMem(a, b) AllocYell((long) a, (long) b, __FUNC__, (long) __LINE__)
  16. #define _FreeMem(a, b) FreeYell(a, (long) b, __FUNC__, (long) __LINE__)
  17.  
  18.    and it'll tell you about all the memory you allocate and free.  It'll let
  19.    you know in what order which calls allocate what.  Then you just need some
  20.    kinda filter to spot mismatches and you're all set.  I'll make one out of
  21.    Uedit.  Something like this:
  22.  
  23. Match up allocation/deallocation reports in program output
  24. <ramiga-8:    movecursor(curfile, sfile)
  25.         if (not insertchar(curfile, " ")) {
  26.             putmsg("Cannot be used on read only buffer!")
  27.             returnfalse
  28.         }
  29.         putmsg("Checking...")
  30.         insertchar(curfile, eline)
  31.         movecursor(curfile, sfile)
  32.         getsearch(buf49)
  33.         equatenum(n0, 0)
  34.         setsearch("
  35. ## Allocated ")
  36.         while (search(curfile, sinvert, einvert, 1)) {
  37.             equateloc(curfile, sinvert, einvert)
  38.             while (not is(curfile, ":")) movecursor(curfile, echar)
  39.             equateloc(curfile, einvert, atcursor)
  40.             freebuf(buf54)
  41.             insertrgn(buf54, efile, curfile, invert)
  42.             insertrgn(buf54, sfile, "
  43. %% Freed ", all)
  44.             setsearch(buf54)
  45.             equateloc(curfile, mouseloc, sinvert)
  46.             movecursor(curfile, einvert)
  47.             if (search(curfile, sinvert, einvert, 1)) {
  48.             movecursor(curfile, echar)
  49.             swapchar(curfile, "-")
  50.             movecursor(curfile, mouseloc)
  51.             movecursor(curfile, sline)
  52.             swapchar(curfile, "-")
  53.             } else {
  54.             incnum(n0)
  55.             putmsg("MISMATCH!  Still checking...")
  56.             movecursor(curfile, mouseloc)
  57.             }
  58.         setsearch("
  59. ## Allocated ")
  60.         }
  61.         movecursor(curfile, sfile)
  62.         clearchar(curfile)
  63.         clearchar(curfile)
  64.         if (eqnum(n0, 0)) {
  65.             setsearch("
  66. %% Freed ")
  67.             if (search(curfile, sinvert, einvert, 1))
  68.             putmsg("Unmatched deallocation!")
  69.             else
  70.             putmsg("All allocations freed.")
  71.         } else
  72.             putmsg("There's a memory leak!")
  73.         setsearch(buf49)
  74. >
  75.  */
  76.  
  77. #include <exec/memory.h>
  78. #include <Paul.h>
  79.  
  80.  
  81. #undef put
  82.  
  83. import /* from pureio.c */ void put(), putfmt();
  84. /* caller must OpenPureIO */
  85.  
  86. import adr _AllocMem();
  87. import void _FreeMem();
  88.  
  89.  
  90. #define MC MEMF_CHIP
  91. #define MF MEMF_FAST
  92. #define MP MEMF_PUBLIC
  93. #define MZ MEMF_CLEAR
  94. #define ML MEMF_LARGEST
  95.  
  96.  
  97.  
  98. void pause()
  99. {
  100.     long trash;
  101.     if (IsInteractive(Input()) && Output()) {
  102.     Write(Output(), "Press RETURN: ", 14L);
  103.     Read(Input(), &trash, 1L);
  104.     }
  105. }
  106.  
  107.  
  108.  
  109. adr AllocYell(s, f, y, l) long s, f; str y; long l;
  110. {
  111.     register adr foo = _AllocMem(s, f);
  112.     union {
  113.     long w;
  114.     char n[4];
  115.     } t;
  116.     short i = 0;
  117.     t.w = 0;
  118.     if (f & MC)
  119.     t.n[i++] = 'C';
  120.     if (f & MP)
  121.     t.n[i++] = 'P';
  122.     if (f & MZ)
  123.     t.n[i++] = 'Z';
  124.     if (!i)
  125.     t.w = 'any\0';
  126.     if (foo)
  127.     putfmt("## Allocated %ld at 0x%lx: ", s, foo);
  128.     else
  129.     putfmt("++ FAILED to allocate %ld bytes ", s);
  130.     putfmt("(%s), in %s line %ld, largest %ld.\n",
  131.         t.n, y, l, AvailMem(ML));
  132.     if (!foo) {
  133.     putfmt("++ AvailMem reports: CHIP %ld total %ld largest,\n     "
  134.         "FAST %ld total %ld largest.\n", AvailMem(MC),
  135.         AvailMem(MC | ML), AvailMem(MF), AvailMem(MF | ML));
  136.     pause();
  137.     }
  138.     return foo;
  139. }
  140.  
  141.  
  142.  
  143. void FreeYell(a, s, y, l) adr a; long s; str y; long l;
  144. {
  145.     if (!TypeOfMem(a) || s <= 0 || s >= 500000) {
  146.     putfmt("++!!  BOGUS FREEMEM:\n   %ld bytes at "
  147.         "0x%lx at line %ld in call %s.\n", s, a, l, y);
  148.     pause();
  149.     return;            /* DON'T free it! */
  150.     }
  151.     putfmt("%%%% Freed %ld at 0x%lx: in call %s line %ld.\n",
  152.         s, a, y, l);
  153.     _FreeMem(a, s);
  154. }
  155.