📄 tmemcheck.c
字号:
{ tmemcheck_error("printf"); } for(count = 0; count < 1024; ++count) { s1 = realloc(s1, count + 1); } if(printf("passed\n") < 0) { tmemcheck_error("printf"); } align = 1; for(bit = 1; align < pagesize; ++bit) { align = 1 << bit; sprintf(buffer, "alignment of %4u", align); free(s1); check_result_error(buffer, (long)(s1 = malloc(align)) % align == 0); } memset(s1, 2, pagesize); check_result_error("malloc pagesize", s1[0] == 2 && s1[pagesize - 1] == 2); free(s1); for(bit = 1; bit <= sizeof(long); ++bit) { s1 = malloc(pagesize - bit); memset(s1, 2, pagesize - bit); sprintf(buffer, "malloc pagesize - %u", bit); check_result_error(buffer, s1[0] == 2 && s1[pagesize - 1 - bit] == 2); free(s1); } for(bit = 1; bit <= sizeof(long); ++bit) { s1 = malloc(pagesize + bit); memset(s1, 2, pagesize + bit); sprintf(buffer, "malloc pagesize + %u", bit); check_result_error(buffer, s1[0] == 2 && s1[pagesize - 1 + bit] == 2); free(s1); } if(tmemcheck_config.large > 0) { s1 = malloc(tmemcheck_config.large); check_result_error_in_log("large alloc ptr log", MEMCHECK_INFO, "Large allocation"); free(s1); }#ifdef HAVE_SIGACTION s1 = malloc(1); if(sigaction(SIGSEGV, NULL, &act)) { tmemcheck_error("sigaction"); }# ifdef HAVE_SIGINFO_T check_result_error("segv signal handler", act.sa_sigaction != (RETSIGTYPE (*)(int signum, /* Cast away 4th arg */ siginfo_t *info, /* (address) that SunOS */ void *context))tmemcheck_handler); /* _may_ have */# else check_result_error("segv signal handler", act.sa_handler != (RETSIGTYPE (*)(int))tmemcheck_handler);# endif if(sigaction(SIGBUS, NULL, &act)) { tmemcheck_error("sigaction"); }# ifdef HAVE_SIGINFO_T check_result_error("bus signal handler", act.sa_sigaction != (RETSIGTYPE (*)(int signum, /* Cast away 4th arg */ siginfo_t *info, /* (address) that SunOS */ void *context))tmemcheck_handler); /* _may_ have */# else check_result_error("bus signal handler", act.sa_handler != (RETSIGTYPE (*)(int))tmemcheck_handler);# endif free(s1);#endif s1 = malloc(2);#ifdef HAVE_SIGLONGJMP if(!sigsetjmp(tmemcheck_handler_env, 1))#else# ifdef HAVE_LONGJMP if(!setjmp(tmemcheck_handler_env))# endif#endif { tmemcheck_setjmp_active = 1; if(tmemcheck_config.underruns) { s1[0] = s1[-1]; /* This should cause a segment fault. */ } else { s1[0] = s1[2]; /* This should cause a segment fault. */ } tmemcheck_signalled = 0; } tmemcheck_setjmp_active = 0; if(tmemcheck_config.underruns) { check_result_error("read underrun trapping", tmemcheck_signalled != 0); } else { check_result_error("read overrun trapping", tmemcheck_signalled != 0); } if(tmemcheck_config.level >= MEMCHECK_ERROR) { if(tmemcheck_log < 0) { tmemcheck_log = open("memcheck.log", O_RDONLY); } if(tmemcheck_log >= 0) { read(tmemcheck_log, buffer, sizeof(buffer) - 1); lseek(tmemcheck_log, 0, SEEK_END); if(tmemcheck_config.underruns) { check_result_warn("read underrun log", !memcmp(buffer, "Underrun", 8)); check_result_warn("read underrun addr", strtoul(&buffer[12], NULL, 16) == ((unsigned long)s1)-1); } else { check_result_warn("read overrun log", !memcmp(buffer, "Overrun", 7)); check_result_warn("read overrun addr", strtoul(&buffer[11], NULL, 16) == ((unsigned long)s1)+2); } } }#ifdef HAVE_SIGLONGJMP if(!sigsetjmp(tmemcheck_handler_env, 1))#else# ifdef HAVE_LONGJMP if(!setjmp(tmemcheck_handler_env))# endif#endif { tmemcheck_setjmp_active = 1; if(tmemcheck_config.underruns) { s1[-1] = s1[0]; /* This should cause a segment fault. */ } else { s1[2] = s1[0]; /* This should cause a segment fault. */ } tmemcheck_signalled = 0; } tmemcheck_setjmp_active = 0; if(tmemcheck_config.underruns) { check_result_error("write underrun trap", tmemcheck_signalled != 0); } else { check_result_error("write overrun trapping", tmemcheck_signalled != 0); } if(tmemcheck_config.level >= MEMCHECK_ERROR) { if(tmemcheck_log < 0) { tmemcheck_log = open("memcheck.log", O_RDONLY); } if(tmemcheck_log >= 0) { read(tmemcheck_log, buffer, sizeof(buffer) - 1); lseek(tmemcheck_log, 0, SEEK_END); if(tmemcheck_config.underruns) { check_result_warn("write underrun log", !memcmp(buffer, "Underrun", 8)); check_result_warn("write underrun addr", strtoul(&buffer[11], NULL, 16) == ((unsigned long)s1) + -1); } else { check_result_warn("write overrun log", !memcmp(buffer, "Overrun", 7)); check_result_warn("write overrun addr", strtoul(&buffer[11], NULL, 16) == ((unsigned long)s1) + 2); } } } free(&s1[1]); check_result_error_in_log("free bad pointer log", MEMCHECK_ERROR, "Invalid"); free(s1); check_result_error_in_log("double free log", MEMCHECK_ERROR, "Already freed"); s1 = malloc(1); if(tmemcheck_config.underruns) { s1[1] = 2; } else { s1[-1] = 2; } free(s1); if(tmemcheck_config.underruns) { check_result_error_in_log("write overrun log", MEMCHECK_ERROR, "Detected overrun"); } else { check_result_error_in_log("write underrun log", MEMCHECK_ERROR, "Detected underrun"); } s1 = malloc(1); line[0] = __LINE__; s1 = realloc(s1, pagesize + 1); line[1] = __LINE__; free(s1); line[2] = __LINE__; free(s1); if(tmemcheck_config.level >= MEMCHECK_ERROR) { if(tmemcheck_log < 0) { tmemcheck_log = open("memcheck.log", O_RDONLY); } if(tmemcheck_log >= 0) { read(tmemcheck_log, buffer, sizeof(buffer) - 1); lseek(tmemcheck_log, 0, SEEK_END); check_result_error("reallocation tracking", strtoul(strchr(strstr(buffer, "realloc"), ':') + 1, NULL, 0) == line[1]); } } s1 = malloc(1); tmemcheck_fail = 0; exit(tmemcheck_result);}static void tmemcheck_error(const char *s){#ifdef HAVE_PERROR perror(s);#else# ifdef HAVE_STRERROR fprintf(stderr, "%s: %s\n", s, strerror(errno));# else# ifdef HAVE_SYS_ERRLIST fprintf(stderr, "%s: %s\n", s, sys_errlist[errno]);# else# ifdef HAVE__SYS_ERRLIST fprintf(stderr, "%s: %s\n", s, _sys_errlist[errno]);# else fprintf(stderr, "%s: errno=%d\n", s, errno);# endif# endif# endif#endif}static void tmemcheck_exit(void){ char buffer[1024]; if(tmemcheck_config.level >= MEMCHECK_WARN) { if(tmemcheck_log < 0) { tmemcheck_log = open("memcheck.log", O_RDONLY); } if(tmemcheck_log >= 0) { if(tmemcheck_fail == 0) { read(tmemcheck_log, buffer, sizeof(buffer) - 1); lseek(tmemcheck_log, 0, SEEK_END); /* Macro expanded by hand so we can skip the call to exit(). * check_result_error("never freed log", * !memcmp(buffer, "Never freed log", 11)); */ if(printf("Checking %s\t: ", "never freed log") < 0) { tmemcheck_error("printf"); } if(!memcmp(buffer, "Never freed", 11)) { if(printf("passed\n") < 0) { tmemcheck_error("printf"); } } else { if(printf("check manually\n") < 0) { tmemcheck_error("printf"); } /* atexit might call malloc in some implementations. * If so, by the time we get here, we haven't yet called * libmemcheck's exit_handler. Don't fail it, but * rather tell the builder to check the log manually. */ } } close(tmemcheck_log); } }}#ifdef HAVE_SIGINFO_Tstatic RETSIGTYPE tmemcheck_handler(int signum, siginfo_t *info, void *context, void *address){ (void)info;#elsestatic RETSIGTYPE tmemcheck_handler(int signum, int code, void *context, void *address){ (void)code;#endif (void)context; (void)address; if(tmemcheck_setjmp_active != 0) { tmemcheck_signalled = signum;#ifdef HAVE_SIGLONGJMP siglongjmp(tmemcheck_handler_env, 1);#else# ifdef HAVE_LONGJMP longjmp(tmemcheck_handler_env, 1);# endif#endif } else {#ifdef HAVE_PSIGNAL psignal(signum, "Caught signal");#else# ifdef HAVE_STRSIGNAL fprintf(stderr, "Caught signal %s\n", strsignal(signum));# else# ifdef HAVE_SYS_SIGLIST fprintf(stderr, "Caught signal %s\n", sys_siglist[signum]);# else# ifdef HAVE__SYS_SIGLIST fprintf(stderr, "Caught signal %s\n", _sys_siglist[signum]);# else fprintf(stderr, "Caught signal signum=%d\n", signum);# endif# endif# endif#endif abort(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -