📄 dmalloc_t.c
字号:
free(pointer_grid); return final;}/* * Do some special tests as soon as we run the test program. Returns * 1 on success else 0. */static int check_initial_special(void){ void *pnt; int final = 1, iter_c; /********************/ do { int amount; /* * So I ran across a bad check for the seen value versus the * iteration count. It was only seen when there were a greater * number of reallocs to the same pointer at the start of the * program running. */ if (! silent_b) { (void)printf(" Checking realloc(malloc) seen count\n"); } do { /* NOTE: must be less than 1024 because below depends on this */ amount = _dmalloc_rand() % 10; } while (amount == 0); pnt = malloc(amount); if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not allocate %d bytes.\n", amount); } final = 0; break; } for (iter_c = 0; iter_c < 100; iter_c++) { /* change the amount */ pnt = realloc(pnt, amount); if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not reallocate %d bytes.\n", amount); } final = 0; break; } } if (pnt == NULL) { break; } /* * now try freeing the pointer with a free that provides a return * value */ if (dmalloc_free(__FILE__, __LINE__, pnt, DMALLOC_FUNC_FREE) != FREE_NOERROR) { if (! silent_b) { (void)printf(" ERROR: free of realloc(malloc) pointer %lx failed.\n", (unsigned long)pnt); } final = 0; } /* now check the heap to verify tha the freed slot is good */ if (dmalloc_verify(NULL /* check all heap */) != DMALLOC_NOERROR) { if (! silent_b) { (void)printf(" ERROR: dmalloc_verify failed\n"); } final = 0; } } while(0); /********************/ #define NEVER_REUSE_ITERS 20 { void *new_pnt, *pnts[NEVER_REUSE_ITERS]; unsigned int old_flags, amount, check_c; if (! silent_b) { (void)printf(" Checking never-reuse token\n"); } old_flags = dmalloc_debug_current(); dmalloc_debug(old_flags | DEBUG_NEVER_REUSE); for (iter_c = 0; iter_c < NEVER_REUSE_ITERS; iter_c++) { amount = 1024; pnts[iter_c] = malloc(amount); if (pnts[iter_c] == NULL) { if (! silent_b) { (void)printf(" ERROR: could not allocate %d bytes.\n", amount); } final = 0; break; } } /* now free them */ for (iter_c = 0; iter_c < NEVER_REUSE_ITERS; iter_c++) { if (dmalloc_free(__FILE__, __LINE__, pnts[iter_c], DMALLOC_FUNC_FREE) != FREE_NOERROR) { if (! silent_b) { (void)printf(" ERROR: free of pointer %lx failed.\n", (unsigned long)pnts[iter_c]); } final = 0; } } /* * now allocate them again and make sure we don't get the same * pointers */ for (iter_c = 0; iter_c < NEVER_REUSE_ITERS; iter_c++) { amount = 1024; new_pnt = malloc(amount); if (new_pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not allocate %d bytes.\n", amount); } final = 0; } /* did we get a previous pointer? */ for (check_c = 0; check_c < NEVER_REUSE_ITERS; check_c++) { if (new_pnt == pnts[check_c]) { if (! silent_b) { (void)printf(" ERROR: pointer %lx was improperly reused.\n", (unsigned long)new_pnt); } final = 0; break; } } if (dmalloc_free(__FILE__, __LINE__, new_pnt, DMALLOC_FUNC_FREE) != FREE_NOERROR) { if (! silent_b) { (void)printf(" ERROR: free of pointer %lx failed.\n", (unsigned long)new_pnt); } final = 0; } } dmalloc_debug(old_flags); } /********************/ return final;}/* * Do some special tests, returns 1 on success else 0 */static int check_special(void){ void *pnt; int errno_hold = dmalloc_errno, page_size; int final = 1; /* reset the errno */ dmalloc_errno = ERROR_NONE; /* get our page size */ page_size = dmalloc_page_size(); dmalloc_message("-------------------------------------------------------\n"); dmalloc_message("NOTE: ignore any errors until the next ------\n"); /********************/ /* * Check to make sure that we are handling free(0L) correctly. */ if (! silent_b) { (void)printf(" Trying to free 0L pointer.\n"); } free(NULL);#if ALLOW_FREE_NULL if (dmalloc_errno != ERROR_NONE) { if (! silent_b) { (void)printf(" ERROR: free of 0L returned error.\n"); } final = 0; }#else if (dmalloc_errno == ERROR_NONE) { if (! silent_b) { (void)printf(" ERROR: free of 0L did not return error.\n"); } final = 0; } else { dmalloc_errno = ERROR_NONE; }#endif /* now test the dmalloc_free function */ if (dmalloc_free(__FILE__, __LINE__, NULL, DMALLOC_FUNC_FREE) != FREE_ERROR) { if (! silent_b) { (void)printf(" ERROR: free of NULL should have failed.\n"); } final = 0; } /********************/ /* * Check to make sure that large mallocs are handled correctly. */ if (! silent_b) { (void)printf(" Allocating a block of too-many bytes.\n"); } pnt = malloc(LARGEST_ALLOCATION + 1); if (pnt == NULL) { dmalloc_errno = ERROR_NONE; } else { if (! silent_b) { (void)printf(" ERROR: allocation of > largest allowed size did not return error.\n"); } free(pnt); final = 0; } /********************/ /* * Check to see if overwritten freed memory is detected. */ if (dmalloc_verify(NULL /* check all heap */) == DMALLOC_NOERROR) { int iter_c, amount, where; unsigned int old_flags; unsigned char ch_hold; old_flags = dmalloc_debug_current(); dmalloc_debug(old_flags | DEBUG_FREE_BLANK); if (! silent_b) { (void)printf(" Overwriting free memory.\n"); } for (iter_c = 0; iter_c < 20; iter_c++) { do { amount = _dmalloc_rand() % (page_size * 3); } while (amount == 0); pnt = malloc(amount); if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not allocate %d bytes.\n", amount); } final = 0; continue; } free(pnt); /* find out where overwrite inside of the pointer */ where = _dmalloc_rand() % amount; ch_hold = *((char *)pnt + where); *((char *)pnt + where) = 'h'; /* now verify that the pnt and the whole heap register errors */ if (dmalloc_verify(pnt) == DMALLOC_NOERROR || dmalloc_verify(NULL /* check all heap */) == DMALLOC_NOERROR) { if (! silent_b) { (void)printf(" ERROR: overwriting free memory not detected.\n"); } final = 0; dmalloc_errno = ERROR_FREE_OVERWRITTEN; } else if (dmalloc_errno == ERROR_FREE_OVERWRITTEN) { dmalloc_errno = ERROR_NONE; } else { if (! silent_b) { (void)printf(" ERROR: verify of overwritten memory returned: %s\n", dmalloc_strerror(dmalloc_errno)); } final = 0; } *((char *)pnt + where) = ch_hold; } dmalloc_debug(old_flags); } /********************/ /* * Check to see if the space above an allocated pnt is detected. */ { int iter_c, amount, where; unsigned int old_flags; DMALLOC_SIZE tot_size; unsigned char ch_hold; old_flags = dmalloc_debug_current(); /* sure on free-blank on and check-fence off */ dmalloc_debug((old_flags | DEBUG_ALLOC_BLANK) & (~DEBUG_CHECK_FENCE)); if (! silent_b) { (void)printf(" Overwriting memory above allocation.\n"); } for (iter_c = 0; iter_c < 20; /* iter_c ++ below */) { do { amount = _dmalloc_rand() % (page_size * 3); } while (amount == 0); pnt = malloc(amount); if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not allocate %d bytes.\n", amount); } final = 0; continue; } /* * check out the pointer now to make sure that we have some * space above the pointer */ if (dmalloc_examine(pnt, NULL /* now user size */, &tot_size, NULL /* no file */, NULL /* no line */, NULL /* no return address */, NULL /* no mark */, NULL /* no seen */) != DMALLOC_NOERROR) { if (! silent_b) { (void)printf(" ERROR: examining pointer %lx failed.\n", (unsigned long)pnt); } final = 0; break; } if (tot_size == amount) { /* we need some space to overwrite */ free(pnt); continue; } /* now we can increment */ iter_c++; /* where to overwrite is then a random from 0 to the remainder-1 */ where = _dmalloc_rand() % (tot_size - amount); ch_hold = *((char *)pnt + amount + where); *((char *)pnt + amount + where) = 'h'; /* now verify that the pnt and the whole heap register errors */ if (dmalloc_verify(pnt) == DMALLOC_NOERROR || dmalloc_verify(NULL /* check all heap */) == DMALLOC_NOERROR) { if (! silent_b) { (void)printf(" ERROR: overwriting above allocated memory not detected.\n"); } final = 0; dmalloc_errno = ERROR_FREE_OVERWRITTEN; } else if (dmalloc_errno == ERROR_FREE_OVERWRITTEN) { dmalloc_errno = ERROR_NONE; } else { if (! silent_b) { (void)printf(" ERROR: verify of overwritten above allocated memory returned: %s\n", dmalloc_strerror(dmalloc_errno)); } final = 0; } *((char *)pnt + amount + where) = ch_hold; free(pnt); } dmalloc_debug(old_flags); } /********************/ /* * See if we can free invalid pointers and get the appropriate errors */ { int iter_c, amount, wrong; if (! silent_b) { (void)printf(" Freeing invalid pointers\n"); } for (iter_c = 0; iter_c < 20; iter_c++) { do { amount = _dmalloc_rand() % (page_size * 3); } while (amount == 0); pnt = malloc(amount); if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not allocate %d bytes.\n", amount); } final = 0; continue; } wrong = _dmalloc_rand() % amount; if (wrong == 0) { wrong = 1; } if (dmalloc_free(__FILE__, __LINE__, (char *)pnt + wrong, DMALLOC_FUNC_FREE) != FREE_NOERROR) { if (dmalloc_errno == ERROR_NOT_START_BLOCK) { dmalloc_errno = ERROR_NONE; } else { if (! silent_b) { (void)printf(" ERROR: free bad pointer produced: %s\n", dmalloc_strerror(dmalloc_errno)); } final = 0; } } else { if (! silent_b) { (void)printf(" ERROR: no problem freeing bad pointer.\n"); } final = 0; dmalloc_errno = ERROR_NOT_FOUND; } free(pnt); } } /********************/ /* * Saw a number of problems where the used_iter value was not being * set and the proper flags were not being set on the slots. */ { char *loc_file, *ex_file; void *new_pnt; unsigned int amount, loc_line, ex_line, old_flags; unsigned long loc_mark, ex_mark, old_seen, ex_seen; DMALLOC_SIZE ex_user_size, ex_tot_size; int iter_c; if (! silent_b) { (void)printf(" Checking dmalloc_examine information\n"); } old_flags = dmalloc_debug_current(); /* * We have to turn off the realloc-copy and new-reuse flags * otherwise this won't work. */ dmalloc_debug(old_flags & ~DEBUG_REALLOC_COPY & ~DEBUG_NEVER_REUSE); for (iter_c = 0; iter_c < 20; iter_c++) { do { amount = _dmalloc_rand() % (page_size * 3); /* we need 2 because we are doing a 2-1 below */ } while (amount < 2); pnt = malloc(amount); loc_file = __FILE__; loc_line = __LINE__; if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not allocate %d bytes.\n", amount); } final = 0; continue; } /* record the mark */ loc_mark = dmalloc_mark(); /* check out the pointer */ if (dmalloc_examine(pnt, &ex_user_size, &ex_tot_size, &ex_file, &ex_line, NULL /* no return address */, &ex_mark, &ex_seen) != DMALLOC_NOERROR) { if (! silent_b) { (void)printf(" ERROR: examining pointer %lx failed.\n", (unsigned long)pnt); } final = 0; } else if (ex_user_size != amount || ex_file == NULL || strcmp(ex_file, loc_file) != 0 || ex_line != loc_line || ex_mark <= 0 || ex_mark != loc_mark || ex_tot_size < ex_user_size || ex_seen < 1) { if (! silent_b) { (void)printf(" ERROR: examined pointer info invalid.\n"); } final = 0; } old_seen = ex_seen; /* * Now realloc the pointer again and make sure that the mark and * the seen increment by 1. We decrement instead of
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -