Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencmddbg.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
1.7.6.1
|