ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cmddbg.c
Go to the documentation of this file.
00001 #include <precomp.h>
00002 
00003 #ifdef _DEBUG_MEM
00004 
00005 #define REDZONE_SIZE  32
00006 #define REDZONE_LEFT 0x78
00007 #define REDZONE_RIGHT 0x87
00008 
00009 typedef struct
00010 {
00011     size_t size;
00012     LIST_ENTRY list_entry;
00013     const char *file;
00014     int line;
00015 } alloc_info, *palloc_info;
00016 
00017 static size_t allocations = 0;
00018 static size_t allocated_memory = 0;
00019 static LIST_ENTRY alloc_list_head = {&alloc_list_head, &alloc_list_head};
00020 
00021 static void *
00022 get_base_ptr(void *ptr)
00023 {
00024     return (void *)((UINT_PTR)ptr - REDZONE_SIZE - sizeof(alloc_info));
00025 }
00026 
00027 static void *
00028 get_ptr_from_base(palloc_info info)
00029 {
00030     return (void*)((size_t)(info + 1) + REDZONE_SIZE);
00031 }
00032 
00033 static void *
00034 write_redzone(void *ptr, size_t size, const char *file, int line)
00035 {
00036     void *ret;
00037     palloc_info info = (palloc_info)ptr;
00038 
00039     info->size = size;
00040     info->file = file;
00041     info->line = line;
00042 
00043     ptr = (void *)(info + 1);
00044     memset(ptr, REDZONE_LEFT, REDZONE_SIZE);
00045     ret = (void *)((size_t)ptr + REDZONE_SIZE);
00046     ptr = (void *)((size_t)ret + size);
00047     memset(ptr, REDZONE_RIGHT, REDZONE_SIZE);
00048     return ret;
00049 }
00050 
00051 static int
00052 check_redzone_region(void *ptr, unsigned char sig, void **newptr)
00053 {
00054     unsigned char *p, *q;
00055     int ret = 1;
00056 
00057     p = (unsigned char *)ptr;
00058     q = p + REDZONE_SIZE;
00059     while (p != q)
00060     {
00061         if (*(p++) != sig)
00062             ret = 0;
00063     }
00064 
00065     if (newptr != NULL)
00066         *newptr = p;
00067     return ret;
00068 }
00069 
00070 static void
00071 redzone_err(const char *msg, palloc_info info, void *ptr, const char *file, int line)
00072 {
00073     DbgPrint("CMD: %s\n", msg);
00074     DbgPrint("     Block: 0x%p Size: %lu\n", ptr, info->size);
00075     DbgPrint("     Allocated from %s:%d\n", info->file, info->line);
00076     DbgPrint("     Detected at: %s:%d\n", file, line);
00077     ASSERT(FALSE);
00078     ExitProcess(1);
00079 }
00080 
00081 static void
00082 check_redzone(void *ptr, const char *file, int line)
00083 {
00084     palloc_info info = (palloc_info)ptr;
00085     ptr = (void *)(info + 1);
00086     if (!check_redzone_region(ptr, REDZONE_LEFT, &ptr))
00087         redzone_err("Detected buffer underflow!", info, ptr, file, line);
00088     ptr = (void *)((UINT_PTR)ptr + info->size);
00089     if (!check_redzone_region(ptr, REDZONE_RIGHT, NULL))
00090         redzone_err("Detected buffer overflow!", info, ptr, file, line);
00091 }
00092 
00093 static size_t
00094 calculate_size_with_redzone(size_t size)
00095 {
00096     return sizeof(alloc_info) + size + (2 * REDZONE_SIZE);
00097 }
00098 
00099 static void
00100 add_mem_to_list(void *ptr)
00101 {
00102     palloc_info info = (palloc_info)ptr;
00103     InsertTailList(&alloc_list_head, &info->list_entry);
00104 }
00105 
00106 static void
00107 del_mem_from_list(void *ptr)
00108 {
00109     palloc_info info = (palloc_info)ptr;
00110     RemoveEntryList(&info->list_entry);
00111 }
00112 
00113 static void
00114 dump_mem_list(void)
00115 {
00116     palloc_info info;
00117     PLIST_ENTRY entry;
00118     void *ptr;
00119 
00120     entry = alloc_list_head.Flink;
00121     while (entry != &alloc_list_head)
00122     {
00123         info = CONTAINING_RECORD(entry, alloc_info, list_entry);
00124 
00125         DbgPrint(" * Block: 0x%p Size: %lu allocated from %s:%d\n", get_ptr_from_base(info), info->size, info->file, info->line);
00126 
00127         ptr = (void *)(info + 1);
00128         if (!check_redzone_region(ptr, REDZONE_LEFT, &ptr))
00129         {
00130             DbgPrint("   !!! Detected buffer underflow !!!\n");
00131         }
00132 
00133         ptr = (void *)((UINT_PTR)ptr + info->size);
00134         if (!check_redzone_region(ptr, REDZONE_RIGHT, NULL))
00135         {
00136             DbgPrint("   !!! Detected buffer overflow !!!\n");
00137         }
00138 
00139         entry = entry->Flink;
00140     }
00141 }
00142 
00143 void *
00144 cmd_alloc_dbg(size_t size, const char *file, int line)
00145 {
00146     void *newptr = NULL;
00147 
00148     newptr = malloc(calculate_size_with_redzone(size));
00149     if (newptr != NULL)
00150     {
00151         allocations++;
00152         allocated_memory += size;
00153         add_mem_to_list(newptr);
00154         newptr = write_redzone(newptr, size, file, line);
00155     }
00156 
00157     return newptr;
00158 }
00159 
00160 void *
00161 cmd_realloc_dbg(void *ptr, size_t size, const char *file, int line)
00162 {
00163     size_t prev_size;
00164     void *newptr = NULL;
00165 
00166     if (ptr == NULL)
00167         return cmd_alloc_dbg(size, file, line);
00168     if (size == 0)
00169     {
00170         cmd_free_dbg(ptr, file, line);
00171         return NULL;
00172     }
00173 
00174     ptr = get_base_ptr(ptr);
00175     prev_size = ((palloc_info)ptr)->size;
00176     check_redzone(ptr, file, line);
00177 
00178     del_mem_from_list(ptr);
00179     newptr = realloc(ptr, calculate_size_with_redzone(size));
00180     if (newptr != NULL)
00181     {
00182         allocated_memory += size - prev_size;
00183         add_mem_to_list(newptr);
00184         newptr = write_redzone(newptr, size, file, line);
00185     }
00186     else
00187         add_mem_to_list(ptr);
00188 
00189     return newptr;
00190 }
00191 
00192 void
00193 cmd_free_dbg(void *ptr, const char *file, int line)
00194 {
00195     if (ptr != NULL)
00196     {
00197         ptr = get_base_ptr(ptr);
00198         check_redzone(ptr, file, line);
00199         allocations--;
00200         allocated_memory -= ((palloc_info)ptr)->size;
00201         del_mem_from_list(ptr);
00202     }
00203 
00204     free(ptr);
00205 }
00206 
00207 TCHAR *
00208 cmd_dup_dbg(const TCHAR *str, const char *file, int line)
00209 {
00210     TCHAR *ptr = NULL;
00211 
00212     if (str != NULL)
00213     {
00214         ptr = (TCHAR *)cmd_alloc_dbg((_tcslen(str) + 1) * sizeof(TCHAR), file, line);
00215         if (ptr != NULL)
00216         {
00217             _tcscpy(ptr, str);
00218         }
00219     }
00220 
00221     return ptr;
00222 }
00223 
00224 void
00225 cmd_checkbuffer_dbg(void *ptr, const char *file, int line)
00226 {
00227     if (ptr != NULL)
00228     {
00229         ptr = get_base_ptr(ptr);
00230         check_redzone(ptr, file, line);
00231     }
00232 }
00233 
00234 void
00235 cmd_exit(int code)
00236 {
00237     if (allocations != 0 || allocated_memory != 0)
00238     {
00239         DbgPrint("CMD: Leaking %lu bytes of memory in %lu blocks! Exit code: %d\n", allocated_memory, allocations, code);
00240         if (allocations != 0)
00241             dump_mem_list();
00242     }
00243 
00244     ExitProcess(code);
00245 }
00246 
00247 #endif /* _DEBUG_MEM */

Generated on Sat May 26 2012 04:17:01 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.