home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / xdme1820.lha / XDME / debug.c < prev    next >
C/C++ Source or Header  |  1993-02-04  |  5KB  |  202 lines

  1.  
  2.      /* (C) Copyright by Dirk Heckmann and Aaron Digulla in D-7750 Konstanz
  3.  
  4.      debug.c
  5.  
  6.       This module provides everything to write save and clean
  7.       programs that allocate memory. This routine handles all
  8.       that's needed for allocating and freeing memory and de-
  9.       bugging the programm itself.
  10.  
  11.       Take care to include "debug_mem.h" in your module, where
  12.       you allocate memory and re-compile it !
  13.  
  14.       I use here code from the allround.lib by Dirk Heckmann.
  15.       Thanks for work, Dirk.
  16.  
  17.      date      done            by
  18.      10.08.90  initial release        D. Heckmann
  19.      01.08.91  modified for debug    A. Digulla
  20.  
  21.      TODO
  22.       The method of replacing Message() by printf() has to be replaced.
  23.       We need a Requester or Alert here (especially for WB-Startup).
  24.  
  25. */
  26.  
  27.      /* Some defs and things we need in this module */
  28.  
  29. #include <exec/types.h>
  30. #include <exec/execbase.h>
  31. #include <exec/memory.h>
  32. #include <clib/exec_protos.h>
  33. #include <clib/dos_protos.h>
  34. #include <string.h>
  35.  
  36. #define DEBUG_C
  37. #include "debug_mem.h"
  38.  
  39. extern struct ExecBase * SysBase;
  40. #define ALLOCERROR     (1L << 31)
  41. #include <stdio.h>
  42.  
  43.  
  44. char message[256];     /* Place for the Output */
  45.  
  46.      /* _debug_AllocMem ()
  47.  
  48.      PARAMETER
  49.       long           size             ; like AllocMem ()
  50.       long           requirements         ; like AllocMem ()
  51.       const char * infotext          ; NEW !
  52.  
  53.      RETURN
  54.       void *
  55.  
  56.      DESCRIPTION
  57.  
  58.       This Function provides what every Amiga-Programmer always
  59.       wanted: a SAVE way of allocating memory. _debug_AllocMem
  60.       will write the size and position and name of the memory-
  61.       block in the TaskMem-list (which is tracked by Exec). So
  62.       we can check the block in _debug_FreeMem (no more gurus
  63.       8100000[59] !) and look whether there is memory left at
  64.       exitus.
  65.  
  66.       BEWARE: The infotext is NOT copied. YOU MUST NOT MODIFY
  67.       IT. It is defined in debug_mem.h.
  68.  
  69.       Because of the wonderful ability of DICE to create __auto-
  70.       exit-functions, we can then check for all non-freed mem-
  71.       ory ! */
  72.  
  73. void * _debug_AllocMem (long size, long reqs, const char * infotext)
  74.  
  75. {
  76.      struct MemList * ml;        /* Received from Exec via AllocEntry */
  77.      struct MemList   block;        /* That's what we want from Exec */
  78.      struct List    * tmem_list;    /* Pointer to the TaskMem-list */
  79.  
  80.       /* Initialize tmem_list */
  81.  
  82.      tmem_list = &SysBase->ThisTask->tc_MemEntry;
  83.  
  84.       /* Fill in the block with the requirements */
  85.  
  86.      block.ml_NumEntries       = 1;      /* just one entry */
  87.      block.ml_ME[0].me_Reqs       = reqs;   /* the requirements (MEMF_xxxx) */
  88.      block.ml_ME[0].me_Length       = size;   /* the size we want */
  89.  
  90.      ml = AllocEntry (&block);          /* get it */
  91.  
  92.      if ((ULONG)ml & ALLOCERROR)        /* Success ? */
  93.       return (NULL);                     /* sad */
  94.  
  95.       /* Add block to TaskMem-list */
  96.      AddTail (tmem_list, &ml->ml_Node);
  97.  
  98.       /* Add the infotext, so _debug_FreeAllMem() can find it */
  99.      ml->ml_Node.ln_Name = infotext;
  100.  
  101.      return (ml->ml_ME[0].me_Addr);   /* Give back address */
  102. } /* _debug_AllocMem () */
  103.  
  104.  
  105.      /* _debug_FreeMem ()
  106.  
  107.      PARAMETER
  108.       void         * memorypointer
  109.       long           blocksize
  110.       const char * infotext
  111.  
  112.      RETURN
  113.       - none -
  114.  
  115.      DESCRIPTION
  116.  
  117.       This is the opposite to _debug_AllocMem(). Here we give the
  118.       memory back to the system ... AFTER SOME CHECKS. So we will
  119.       never get any gurus for this !
  120.  
  121.       If _debug_FreeMem fails, we will get a message with more
  122.       information, why. */
  123.  
  124. void _debug_FreeMem (void * memptr, long size, const char * infotext)
  125.  
  126. {
  127.      struct MemList * ml;        /* This is what we found */
  128.      struct List    * tmem_list;    /* and here we look for it */
  129.  
  130.       /* Initialize tmem_list */
  131.  
  132.      tmem_list = &SysBase->ThisTask->tc_MemEntry;
  133.  
  134.       /* Get first entry out of the TaskMem-list */
  135.  
  136.      ml = (struct MemList *)tmem_list->lh_Head;
  137.  
  138.      while (ml->ml_Node.ln_Succ)
  139.      {
  140.       if (ml->ml_ME[0].me_Addr == memptr)
  141.       { /* found it ? */
  142.            struct MemEntry * me = ml->ml_ME;
  143.  
  144.            if (me->me_Length != size)
  145.            {
  146.             sprintf (message, "FreeMem(): Warning: Size mismatch error (old %d new %d)\n\t%s\n",
  147.              me->me_Length, size, infotext);
  148.             Write (Output(), message, strlen(message));
  149.             Delay (50);
  150.            }
  151.  
  152.            Remove (&ml->ml_Node);
  153.            FreeEntry (ml);
  154.            return ;
  155.       }
  156.  
  157.       ml = (struct MemList *)ml->ml_Node.ln_Succ;
  158.      } /* while ((struct Node *)ml->ln_Succ) */
  159.  
  160.      sprintf (message, "FreeMem(): Error: Memory not found (Addr $%08x Size %d)\n\t%s\n",
  161.       memptr, size, infotext);
  162.      Write (Output(), message, strlen(message));
  163.     Delay (50);
  164. } /* _debug_FreeMem () */
  165.  
  166.  
  167. void _debug_FreeAllMem (void)
  168.  
  169. {
  170.      struct MemList * ml;        /* This is what we found */
  171.      struct List    * tmem_list;    /* and here we look for it */
  172.  
  173.       /* Initialize tmem_list */
  174.  
  175.      tmem_list = &SysBase->ThisTask->tc_MemEntry;
  176.  
  177.       /* Get first entry out of the TaskMem-list */
  178.  
  179.      ml = (struct MemList *)tmem_list->lh_Head;
  180.  
  181.      while (ml->ml_Node.ln_Succ)
  182.      {
  183.       if (strncmp (ml->ml_Node.ln_Name, "AllocMem()", 10) == 0)
  184.       {
  185.              /* found an entry */
  186.            struct MemEntry * me = ml->ml_ME;
  187.  
  188.            sprintf (message, "FreeAllMem(): Error: Forgotten Memory (Addr $%08x Size %d)\n\t%s\n",
  189.             me->me_Addr, me->me_Length, ml->ml_Node.ln_Name);
  190.            Write (Output(), message, strlen(message));
  191.            Delay (50);
  192.  
  193.            Remove (&ml->ml_Node);
  194.            FreeEntry (ml);
  195.       }
  196.  
  197.       ml = (struct MemList *)ml->ml_Node.ln_Succ;
  198.      } /* while ((struct Node *)ml->ln_Succ) */
  199. } /* FreeAllMem () */
  200.  
  201.  
  202.