00001
00002
00003 #include "dbg_mem.h"
00004 #include "rcs_prnt.hh"
00005 #include "linklist.hh"
00006
00007 RCS_LINKED_LIST *dbg_mem_list = NULL;
00008
00009 int log_debug_mem_list;
00010 int print_debug_mem_calls;
00011 int next_log_debug_id;
00012
00013 struct DEBUG_MEM_ENTRY
00014 {
00015 public:
00016 void *address;
00017 const char *file;
00018 int line;
00019 size_t size;
00020 int id;
00021 };
00022
00023
00024
00025 void
00026 enable_debug_memory ()
00027 {
00028 log_debug_mem_list = 1;
00029 print_debug_mem_calls = 1;
00030 next_log_debug_id = 0;
00031 }
00032
00033 void
00034 disable_debug_memory ()
00035 {
00036 log_debug_mem_list = 0;
00037 print_debug_mem_calls = 0;
00038 next_log_debug_id = 0;
00039 }
00040
00041
00042 void
00043 clear_dbg_mem_list ()
00044 {
00045 log_debug_mem_list = 0;
00046 next_log_debug_id = 0;
00047 if (NULL != dbg_mem_list)
00048 {
00049 delete dbg_mem_list;
00050 dbg_mem_list = NULL;
00051 }
00052 }
00053
00054 void
00055 print_dbg_mem_list ()
00056 {
00057 if (NULL == dbg_mem_list)
00058 {
00059 rcs_print ("Debug memory list is NULL.\n");
00060 return;
00061 }
00062 rcs_print ("\tAddress \tsize \tid \tFile \tline\n");
00063 DEBUG_MEM_ENTRY *dbg_mem_entry =
00064 (DEBUG_MEM_ENTRY *) dbg_mem_list->get_head ();
00065 while (NULL != dbg_mem_entry)
00066 {
00067 rcs_print ("%p \t%d(0x%X) \t%d \t%s \t%d\n", dbg_mem_entry->address,
00068 dbg_mem_entry->size, dbg_mem_entry->size, dbg_mem_entry->id,
00069 dbg_mem_entry->file, dbg_mem_entry->line);
00070 dbg_mem_entry = (DEBUG_MEM_ENTRY *) dbg_mem_list->get_next ();
00071 }
00072 }
00073
00074 void
00075 add_dbg_mem_list (const char *file, int line, void *address, size_t sz)
00076 {
00077 DEBUG_MEM_ENTRY dbg_mem_entry;
00078 dbg_mem_entry.address = address;
00079 dbg_mem_entry.size = sz;
00080 dbg_mem_entry.file = file;
00081 dbg_mem_entry.line = line;
00082 dbg_mem_entry.id = next_log_debug_id++;
00083 log_debug_mem_list = 0;
00084 if (NULL == dbg_mem_list)
00085 {
00086 dbg_mem_list = new RCS_LINKED_LIST ();
00087 }
00088 dbg_mem_list->store_at_tail (&dbg_mem_entry, sizeof (DEBUG_MEM_ENTRY), 1);
00089 log_debug_mem_list = 1;
00090 }
00091
00092 void
00093 delete_dbg_mem_list (void *address)
00094 {
00095 if (NULL != dbg_mem_list)
00096 {
00097 log_debug_mem_list = 0;
00098 DEBUG_MEM_ENTRY *dbg_mem_entry =
00099 (DEBUG_MEM_ENTRY *) dbg_mem_list->get_head ();
00100 while (NULL != dbg_mem_entry)
00101 {
00102 if (dbg_mem_entry->address == address)
00103 {
00104 dbg_mem_list->delete_current_node ();
00105 break;
00106 }
00107 dbg_mem_entry = (DEBUG_MEM_ENTRY *) dbg_mem_list->get_next ();
00108 }
00109 log_debug_mem_list = 1;
00110 }
00111 }
00112
00113
00114 void *
00115 debug_malloc (const char *file, int line, size_t s)
00116 {
00117 void *ret = malloc (s);
00118 if (log_debug_mem_list)
00119 {
00120 add_dbg_mem_list (file, line, ret, s);
00121 }
00122 if (print_debug_mem_calls)
00123 {
00124 rcs_print ("%p = malloc(%d)\n", ret, s);
00125 }
00126 return ret;
00127 }
00128
00129 void *
00130 debug_calloc (const char *file, int line, size_t nelem, size_t elsize)
00131 {
00132 void *ret = calloc (nelem, elsize);
00133 if (log_debug_mem_list)
00134 {
00135 add_dbg_mem_list (file, line, ret, nelem * elsize);
00136 }
00137 if (print_debug_mem_calls)
00138 {
00139 rcs_print ("%p = calloc(%d,%d)\n", ret, nelem, elsize);
00140 }
00141 return ret;
00142 }
00143
00144 void *
00145 debug_realloc (const char *file, int line, void *ptr, size_t s)
00146 {
00147 void *orig_ptr = ptr;
00148 if (log_debug_mem_list)
00149 {
00150 delete_dbg_mem_list (orig_ptr);
00151 }
00152 void *new_ptr = NULL;
00153 new_ptr = realloc (ptr, s);
00154 if (log_debug_mem_list)
00155 {
00156 add_dbg_mem_list (file, line, new_ptr, s);
00157 }
00158 if (print_debug_mem_calls)
00159 {
00160 rcs_print ("%p = realloc(%p,%d)\n", new_ptr, orig_ptr, s);
00161 }
00162 return new_ptr;
00163 }
00164
00165 void
00166 debug_free (void *ptr)
00167 {
00168 if (print_debug_mem_calls)
00169 {
00170 rcs_print ("free(%p)\n", ptr);
00171 }
00172 if (log_debug_mem_list)
00173 {
00174 delete_dbg_mem_list (ptr);
00175 }
00176 if (NULL != ptr)
00177 {
00178 free (ptr);
00179 }
00180 }
00181
00182 #ifdef DEBUG_MEMORY
00183
00184 void *operator
00185 new (size_t s)
00186 {
00187 return DEBUG_MALLOC (s);
00188 }
00189
00190 void operator
00191 delete (void *ptr)
00192 {
00193 DEBUG_FREE (ptr);
00194 }
00195
00196 #endif