📄 dmalloc_t.c
字号:
{ unsigned long size; unsigned int old_flags = dmalloc_debug_current(); char save_ch; if (! silent_b) { (void)printf(" Checking per-pointer blanking flags\n"); } /* disable alloc and check blanking */ dmalloc_debug(old_flags & (~(DEBUG_ALLOC_BLANK | DEBUG_CHECK_BLANK))); /* allocate a pointer */ size = _dmalloc_rand() % MAX_ALLOC + 10; pnt = malloc(size); if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not malloc %lu bytes.\n", size); } return 0; } /* now enable alloc and check blanking */ dmalloc_debug(old_flags | DEBUG_ALLOC_BLANK | DEBUG_CHECK_BLANK); if (dmalloc_free(__FILE__, __LINE__, pnt, DMALLOC_FUNC_FREE) != FREE_NOERROR) { if (! silent_b) { (void)printf(" ERROR: per-pointer blanking flags failed: %s\n", dmalloc_strerror(dmalloc_errno)); } final = 0; } /********/ /* now, enable alloc and check blanking */ dmalloc_debug((old_flags | DEBUG_ALLOC_BLANK | DEBUG_CHECK_BLANK) & (~DEBUG_CHECK_FENCE)); /* allocate a pointer */ size = BLOCK_SIZE / 2 + 1; pnt = malloc(size); if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not malloc %lu bytes.\n", size); } return 0; } /* now disable alloc blanking */ dmalloc_debug(old_flags | DEBUG_CHECK_BLANK); /* overwrite one of the top chars */ save_ch = *((char *)pnt + size); *((char *)pnt + size) = '\0'; /* free the pointer should still see the error */ if (dmalloc_free(__FILE__, __LINE__, pnt, DMALLOC_FUNC_FREE) == FREE_NOERROR) { if (! silent_b) { (void)printf(" ERROR: per-pointer blanking flags failed: %s\n", dmalloc_strerror(dmalloc_errno)); } final = 0; } /* restore the overwrite */ *((char *)pnt + size) = save_ch; /* restore flags */ dmalloc_debug(old_flags); } /********************/ /* * Make sure free-blank doesn't imply alloc-blank */ { unsigned long size; unsigned int old_flags = dmalloc_debug_current(); if (! silent_b) { (void)printf(" Checking free versus alloc blank\n"); } /* enable free blank only without fence-post, alloc, or check blank */ dmalloc_debug((old_flags | DEBUG_FREE_BLANK) & (~(DEBUG_CHECK_FENCE | DEBUG_CHECK_BLANK | DEBUG_ALLOC_BLANK))); /* allocate a pointer */ size = BLOCK_SIZE / 2 + 1; pnt = malloc(size); if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not malloc %lu bytes.\n", size); } return 0; } /* overwrite one of the top chars */ *((char *)pnt + size) = '\0'; /* this shouldn't notice */ if (dmalloc_free(__FILE__, __LINE__, pnt, DMALLOC_FUNC_FREE) != FREE_NOERROR) { if (! silent_b) { (void)printf(" ERROR: per-pointer blanking flags failed: %s\n", dmalloc_strerror(dmalloc_errno)); } final = 0; } /* NOTE: no restoring of overwritten chars here because of free-blank */ /* restore flags */ dmalloc_debug(old_flags); } /********************/ /* * Make sure that a pointer reallocating, get's the per-pointer * alloc flags enabled. */ { unsigned long size; unsigned int old_flags = dmalloc_debug_current(); char save_ch; if (! silent_b) { (void)printf(" Checking per-pointer alloc flags and realloc\n"); } /* enable alloc blanking without fence-posts */ dmalloc_debug((old_flags | DEBUG_ALLOC_BLANK) & (~DEBUG_CHECK_FENCE)); /* allocate a pointer that should fill the block */ size = BLOCK_SIZE; pnt = malloc(size); if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not malloc %lu bytes.\n", size); } return 0; } /* now disable all checking */ dmalloc_debug(old_flags & (~(DEBUG_CHECK_FENCE | DEBUG_CHECK_BLANK | DEBUG_ALLOC_BLANK | DEBUG_FREE_BLANK))); pnt = realloc(pnt, size - 1); if (pnt == NULL) { if (! silent_b) { (void)printf(" ERROR: could not realloc %#lx to %lu bytes.\n", (long)pnt, size - 1); } return 0; } /* overwrite one of the top chars */ save_ch = *((char *)pnt + size - 1); *((char *)pnt + size - 1) = '\0'; /* we should notice the overwrite */ if (dmalloc_free(__FILE__, __LINE__, pnt, DMALLOC_FUNC_FREE) == FREE_NOERROR) { if (! silent_b) { (void)printf(" ERROR: per-pointer blanking flags failed: %s\n", dmalloc_strerror(dmalloc_errno)); } final = 0; } /* restore the overwrite */ *((char *)pnt + size - 1) = save_ch; /* restore flags */ dmalloc_debug(old_flags); } /********************/ /* * NOTE: add tests which should result in errors before the ------- * message above */ return final;}/* * Run the interactive section of the program */static void do_interactive(void){ int len; char line[128], *line_p; void *pnt; (void)printf("Malloc test program. Type 'help' for assistance.\n"); while (1) { (void)printf("> "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } line_p = strchr(line, '\n'); if (line_p != NULL) { *line_p = '\0'; } len = strlen(line); if (len == 0) { continue; } if (strncmp(line, "?", len) == 0 || strncmp(line, "help", len) == 0) { (void)printf("\thelp - print this message\n\n"); (void)printf("\tmalloc - allocate memory\n"); (void)printf("\tcalloc - allocate/clear memory\n"); (void)printf("\trealloc - reallocate memory\n"); (void)printf("\trecalloc - reallocate cleared memory\n"); (void)printf("\tmemalign - allocate aligned memory\n"); (void)printf("\tvalloc - allocate page-aligned memory\n"); (void)printf("\tstrdup - allocate a string\n"); (void)printf("\tfree - deallocate memory\n\n"); (void)printf("\tstats - dump heap stats to the logfile\n"); (void)printf("\tunfreed - list the unfree memory to the logfile\n"); (void)printf("\tmark - display the current mark value\n"); (void)printf("\tchanged - display what pointers have changed\n\n"); (void)printf("\tverify - check out a memory address (or all heap)\n"); (void)printf("\toverwrite - overwrite some memory to test errors\n");#if HAVE_SBRK (void)printf("\tsbrk - call sbrk to test external areas\n\n");#endif (void)printf("\trandom - randomly execute a number of [de] allocs\n"); (void)printf("\tspecial - run some special tests\n\n"); (void)printf("\tquit - quit this test program\n"); continue; } if (strncmp(line, "quit", len) == 0) { break; } if (strncmp(line, "malloc", len) == 0) { int size; (void)printf("How much to malloc: "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } size = atoi(line); (void)printf("malloc(%d) returned '%#lx'\n", size, (long)malloc(size)); continue; } if (strncmp(line, "calloc", len) == 0) { int size; (void)printf("How much to calloc: "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } size = atoi(line); (void)printf("calloc(%d) returned '%#lx'\n", size, (long)calloc(size, sizeof(char))); continue; } if (strncmp(line, "realloc", len) == 0) { int size; pnt = get_address(); (void)printf("How much to realloc: "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } size = atoi(line); (void)printf("realloc(%#lx, %d) returned '%#lx'\n", (long)pnt, size, (long)realloc(pnt, size)); continue; } if (strncmp(line, "recalloc", len) == 0) { int size; pnt = get_address(); (void)printf("How much to recalloc: "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } size = atoi(line); (void)printf("realloc(%#lx, %d) returned '%#lx'\n", (long)pnt, size, (long)recalloc(pnt, size)); continue; } if (strncmp(line, "memalign", len) == 0) { int alignment, size; (void)printf("Alignment in bytes: "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } alignment = atoi(line); (void)printf("How much to memalign: "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } size = atoi(line); (void)printf("memalign(%d, %d) returned '%#lx'\n", alignment, size, (long)memalign(alignment, size)); continue; } if (strncmp(line, "valloc", len) == 0) { int size; (void)printf("How much to valloc: "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } size = atoi(line); (void)printf("valloc(%d) returned '%#lx'\n", size, (long)valloc(size)); continue; } if (strncmp(line, "strdup", len) == 0) { (void)printf("Enter a string to strdup: "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } (void)printf("strdup returned '%#lx'\n", (long)strdup(line)); continue; } if (strncmp(line, "free", len) == 0) { pnt = get_address(); free(pnt); continue; } if (strncmp(line, "stats", len) == 0) { dmalloc_log_stats(); (void)printf("Done.\n"); continue; } if (strncmp(line, "unfreed", len) == 0) { dmalloc_log_unfreed(); (void)printf("Done.\n"); continue; } if (strncmp(line, "mark", len) == 0) { (void)printf("Mark is %lu.\n", dmalloc_mark()); continue; } if (strncmp(line, "changed", len) == 0) { (void)printf("Enter the mark: "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } dmalloc_log_changed(atoi(line), 1, 1, 1); (void)printf("Done.\n"); continue; } if (strncmp(line, "overwrite", len) == 0) { char *overwrite = "OVERWRITTEN"; pnt = get_address(); memcpy((char *)pnt, overwrite, strlen(overwrite)); (void)printf("Done.\n"); continue; } #if HAVE_SBRK /* call sbrk directly */ if (strncmp(line, "sbrk", len) == 0) { int size; (void)printf("How much to sbrk: "); if (fgets(line, sizeof(line), stdin) == NULL) { break; } size = atoi(line); (void)printf("sbrk(%d) returned '%#lx'\n", size, (long)sbrk(size)); continue; }#endif /* do random heap hits */ if (strncmp(line, "random", len) == 0) { int iter_n; (void)printf("How many iterations[%d]: ", default_iter_n); if (fgets(line, sizeof(line), stdin) == NULL) { break; } if (line[0] == '\0' || line[0] == '\n') { iter_n = default_iter_n; } else { iter_n = atoi(line); } if (do_random(iter_n)) { (void)printf("It succeeded.\n"); } else { (void)printf("It failed.\n"); } continue; } /* do special checks */ if (strncmp(line, "special", len) == 0) { if (check_special()) { (void)printf("It succeeded.\n"); } else { (void)printf("It failed.\n"); } continue; } if (strncmp(line, "verify", len) == 0) { int ret; (void)printf("If the address is 0, verify will check the whole heap.\n"); pnt = get_address(); ret = dmalloc_verify(pnt); (void)printf("dmalloc_verify(%#lx) returned '%s'\n", (long)pnt, (ret == DMALLOC_NOERROR ? "success" : "failure")); continue; } (void)printf("Unknown command '%s'. Type 'help' for assistance.\n", line); }}/* * Allocation tracking function called each time an allocation occurs. * FILE may be a return address if LINE is 0. FUNC_ID is one of the * above DMALLOC_FUNC_ defines. BYTE_SIZE is how many bytes were * requested with a possible ALIGNMENT. OLD_ADDR is for realloc and * free functions. NEW_ADDR is the pointer returned by the allocation * functions. */static void track_alloc_trxn(const char *file, const unsigned int line, const int func_id, const DMALLOC_SIZE byte_size, const DMALLOC_SIZE alignment, const DMALLOC_PNT old_addr, const DMALLOC_PNT new_addr){ char file_line[64]; if (file == NULL && line == 0) { strcpy(file_line, "unknown"); } else if (line == 0) { (void)loc_snprintf(file_line, sizeof(file_line), "ra=%#lx", (long)file); } else { (void)loc_snprintf(file_line, sizeof(file_line), "%s:%d", file, line); } switch (func_id) { case DMALLOC_FUNC_MALLOC: (void)printf("%s malloc %d bytes got %#lx\n", file_line, byte_size, (long)new_addr); break; case DMALLOC_FUNC_CALLOC: (void)printf("%s calloc %d bytes got %#lx\n", file_line, byte_size, (long)new_addr); break; case DMALLOC_FUNC_REALLOC: (void)printf("%s realloc %d bytes from %#lx got %#lx\n", file_line, byte_size, (long)old_addr, (long)new_addr); break; case DMALLOC_FUNC_RECALLOC: (void)printf("%s recalloc %d bytes from %#lx got %#lx\n", file_line, byte_size, (long)old_addr, (long)new_addr); break; case DMALLOC_FUNC_MEMALIGN: (void)printf("%s memalign %d bytes alignment %d got %#lx\n", file_line, byte_size, alignment, (long)new_addr); break; case DMALLOC_FUNC_VALLOC: (vo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -