/* * Dummy function for checking memcpy's arguments. */ void *_dmalloc_memcpy(const char *file, const int line, void *to, const void *from, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if ((! dmalloc_verify_pnt(file, line, "memcpy", to, 0 /* not exact */, len)) || (! dmalloc_verify_pnt(file, line, "memcpy", from, 0 /* not exact */, len))) { dmalloc_message("bad pointer argument found in memcpy"); } #if HAVE_MEMMOVE /* * If memmove exists, dump out a warning if memcpy is being used * for overlapping memory segments. */ if (((char *)from < (char *)to && (char *)from + len > (char *)to) || ((char *)to < (char *)from && (char *)to + len > (char *)from)) { dmalloc_message("%s:%d: WARNING: memory overlap in memcpy, should use memmove", file, line); } #endif } return (void *)memcpy(to, from, len); }
/* * void dmalloc_error * * DESCRIPTION: * * Handler of error codes. The caller should have set the errno already * * RETURNS: * * None. * * ARGUMENTS: * * func -> Function name for the logs. */ void dmalloc_error(const char *func) { /* do we need to log or print the error? */ if (dmalloc_logpath != NULL || BIT_IS_SET(_dmalloc_flags, DEBUG_PRINT_MESSAGES)) { /* default str value */ if (func == NULL) { func = "_malloc_error"; } /* print the malloc error message */ dmalloc_message("ERROR: %s: %s (err %d)", func, dmalloc_strerror(dmalloc_errno), dmalloc_errno); } /* do I need to abort? */ if (BIT_IS_SET(_dmalloc_flags, DEBUG_ERROR_ABORT)) { _dmalloc_die(0); } #if HAVE_FORK /* how about just drop core? */ if (BIT_IS_SET(_dmalloc_flags, DEBUG_ERROR_DUMP)) { if (fork() == 0) { _dmalloc_die(1); } } #endif }
/* * Dummy function for checking strncasecmp's arguments. */ int _dmalloc_strncasecmp(const char *file, const int line, const char *s1, const char *s2, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { const char *s1_p, *s2_p; int min_size; /* we go through both pointers up to the length characters */ for (s1_p = s1, s2_p = s2; s1_p < s1 + len; s1_p++, s2_p++) { if (*s1_p == '\0' || *s2_p == '\0') { s1_p++; break; } } min_size = s1_p - s1; if ((! dmalloc_verify_pnt(file, line, "strncasecmp", s1, 0 /* not exact */, min_size)) || (! dmalloc_verify_pnt(file, line, "strncasecmp", s2, 0 /* not exact */, min_size))) { dmalloc_message("bad pointer argument found in strncasecmp"); } } return strncasecmp(s1, s2, len); }
/* * Dummy function for checking strncat's arguments. */ char *_dmalloc_strncat(const char *file, const int line, char *to, const char *from, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { const char *from_p; int min_size; /* so we have to figure out the max length of the buffers directly here */ for (from_p = from; from_p < from + len; from_p++) { if (*from_p == '\0') { /* no need to do ++ here because we +1 for the \0 anyway */ break; } } min_size = from_p - from; /* either len or nullc */ if ((! dmalloc_verify_pnt(file, line, "strncat", to, 0 /* not exact */, loc_strlen(file, line, "strncat", to) + min_size + 1)) || (! dmalloc_verify_pnt(file, line, "strncat", from, 0 /* not exact */, min_size))) { dmalloc_message("bad pointer argument found in strncat"); } } return (char *)strncat(to, from, len); }
/* * Dummy function for checking strncmp's arguments. */ int _dmalloc_strncmp(const char *file, const int line, const char *s1, const char *s2, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { const char *s1_p, *s2_p; int min_size; /* so we have to figure out the max length of the buffers directly here */ for (s1_p = s1, s2_p = s2; s1_p < s1 + len; s1_p++, s2_p++) { if (*s1_p == '\0' || *s2_p == '\0') { s1_p++; break; } } min_size = s1_p - s1; /* either len or nullc */ if ((! dmalloc_verify_pnt(file, line, "strncmp", s1, 0 /* not exact */, min_size)) || (! dmalloc_verify_pnt(file, line, "strncmp", s2, 0 /* not exact */, min_size))) { dmalloc_message("bad pointer argument found in strncmp"); } } return strncmp(s1, s2, len); }
/* * Dummy function for checking strncpy's arguments. */ char *_dmalloc_strncpy(const char *file, const int line, char *to, const char *from, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { const char *from_p; int min_size; /* so we have to figure out the max length of the buffers directly here */ for (from_p = from; from_p < from + len; from_p++) { if (*from_p == '\0') { from_p++; break; } } min_size = from_p - from; /* len or until nullc */ if ((! dmalloc_verify_pnt(file, line, "strncpy", to, 0 /* not exact */, min_size)) || (! dmalloc_verify_pnt(file, line, "strncpy", from, 0 /* not exact */, min_size))) { dmalloc_message("bad pointer argument found in strncpy"); } } return (char *)strncpy(to, from, len); }
/* * Dummy function for checking memccpy's arguments. */ void *_dmalloc_memccpy(const char *file, const int line, void *dest, const void *src, const int ch, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { const char *src_p; int min_size; /* so we have to figure out the max length of the buffer directly here */ for (src_p = (char *)src; src_p < (char *)src + len; src_p++) { if (*src_p == ch) { src_p++; break; } } min_size = src_p - (char *)src; /* maybe len maybe first ch */ if ((! dmalloc_verify_pnt(file, line, "memccpy", dest, 0 /* not exact */, min_size)) || (! dmalloc_verify_pnt(file, line, "memccpy", src, 0 /* not exact */, min_size))) { dmalloc_message("bad pointer argument found in memccpy"); } } return (void *)memccpy(dest, src, ch, len); }
static void l2tp_dmalloc_dump(void) { #ifdef L2TP_DMALLOC dmalloc_log_changed(l2tp_dmalloc_mark, 1, 0, 1); l2tp_dmalloc_mark = dmalloc_mark(); dmalloc_message("DMALLOC MARK set to %lu\n", l2tp_dmalloc_mark); #endif }
/* * Dummy function for checking atol's arguments. */ long _dmalloc_atol(const char *file, const int line, const char *str) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if (! dmalloc_verify_pnt(file, line, "atol", str, 0 /* not exact */, -1)) { dmalloc_message("bad pointer argument found in atol"); } } return atol(str); }
/* * void _dmalloc_reopen_log * * DESCRIPTION: * * Re-open our log file which basically calls close() on the * logfile-fd. If we change the name of the log-file then we will * re-open the file. * * RETURNS: * * None. * * ARGUMENTS: * * None. */ void _dmalloc_reopen_log(void) { /* no need to reopen it if it hasn't been reopened yet */ if (outfile_fd < 0) { return; } if (dmalloc_logpath == NULL) { dmalloc_message("Closing logfile to not be reopened"); } else { dmalloc_message("Closing logfile to be reopened as '%s'", dmalloc_logpath); } (void)close(outfile_fd); outfile_fd = -1; /* we don't call open here, we'll let the next message do it */ }
/* * Dummy function for checking strrchr's arguments. */ char *_dmalloc_strrchr(const char *file, const int line, const char *str, const int ch) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if (! dmalloc_verify_pnt(file, line, "strrchr", str, 0 /* not exact */, -1)) { dmalloc_message("bad pointer argument found in strrchr"); } } return (char *)strrchr(str, ch); }
/* * Dummy function for checking bzero's arguments. */ void _dmalloc_bzero(const char *file, const int line, void *buf, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if (! dmalloc_verify_pnt(file, line, "bzero", buf, 0 /* not exact */, len)) { dmalloc_message("bad pointer argument found in bzero"); } } bzero(buf, len); }
/* * Dummy function for checking memset's arguments. */ void *_dmalloc_memset(const char *file, const int line, void *buf, const int ch, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if (! dmalloc_verify_pnt(file, line, "memset", buf, 0 /* not exact */, len)) { dmalloc_message("bad pointer argument found in memset"); } } return (void *)memset(buf, ch, len); }
/* * Dummy function for checking strlen's arguments. */ DMALLOC_SIZE _dmalloc_strlen(const char *file, const int line, const char *str) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if (! dmalloc_verify_pnt(file, line, "strlen", str, 0 /* not exact */, -1)) { dmalloc_message("bad pointer argument found in strlen"); } } return loc_strlen(file, line, "strlen", str); }
/* * Dummy function for checking strspn's arguments. */ int _dmalloc_strspn(const char *file, const int line, const char *str, const char *list) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if ((! dmalloc_verify_pnt(file, line, "strspn", str, 0 /* not exact */, -1)) || (! dmalloc_verify_pnt(file, line, "strspn", list, 0 /* not exact */, -1))) { dmalloc_message("bad pointer argument found in strspn"); } } return strspn(str, list); }
/* * Dummy function for checking memcmp's arguments. */ int _dmalloc_memcmp(const char *file, const int line, const void *b1, const void *b2, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if ((! dmalloc_verify_pnt(file, line, "memcmp", b1, 0 /* not exact */, len)) || (! dmalloc_verify_pnt(file, line, "memcmp", b2, 0 /* not exact */, len))) { dmalloc_message("bad pointer argument found in memcmp"); } } return memcmp(b1, b2, len); }
/* * Dummy function for checking memmove's arguments. */ void *_dmalloc_memmove(const char *file, const int line, void *to, const void *from, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if ((! dmalloc_verify_pnt(file, line, "memmove", to, 0 /* not exact */, len)) || (! dmalloc_verify_pnt(file, line, "memmove", from, 0 /* not exact */, len))) { dmalloc_message("bad pointer argument found in memmove"); } } return (void *)memmove(to, from, len); }
/* * Dummy function for checking strcmp's arguments. */ int _dmalloc_strcmp(const char *file, const int line, const char *s1, const char *s2) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if ((! dmalloc_verify_pnt(file, line, "strcmp", s1, 0 /* not exact */, -1)) || (! dmalloc_verify_pnt(file, line, "strcmp", s2, 0 /* not exact */, -1))) { dmalloc_message("bad pointer argument found in strcmp"); } } return strcmp(s1, s2); }
/* * Dummy function for checking bcopy's arguments. */ void _dmalloc_bcopy(const char *file, const int line, const void *from, void *to, const DMALLOC_SIZE len) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if ((! dmalloc_verify_pnt(file, line, "bcopy", from, 0 /* not exact */, len)) || (! dmalloc_verify_pnt(file, line, "bcopy", to, 0 /* not exact */, len))) { dmalloc_message("bad pointer argument found in bcopy"); } } bcopy(from, to, len); }
/* * Dummy function for checking strcpy's arguments. */ char *_dmalloc_strcpy(const char *file, const int line, char *to, const char *from) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if ((! dmalloc_verify_pnt(file, line, "strcpy", to, 0 /* not exact */, loc_strlen(file, line, "strcpy", from) + 1)) || (! dmalloc_verify_pnt(file, line, "strcpy", from, 0 /* not exact */, -1))) { dmalloc_message("bad pointer argument found in strcpy"); } } return (char *)strcpy(to, from); }
/* * Dummy function for checking strtok's arguments. */ char *_dmalloc_strtok(const char *file, const int line, char *str, const char *sep) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if ((str != NULL && (! dmalloc_verify_pnt(file, line, "strtok", str, 0 /* not exact */, -1))) || (! dmalloc_verify_pnt(file, line, "strtok", sep, 0 /* not exact */, -1))) { dmalloc_message("bad pointer argument found in strtok"); } } return (char *)strtok(str, sep); }
/* * Dummy function for checking strlen's arguments. */ static int loc_strlen(const char *file, const int line, const char *func, const char *str) { int len = 0; const char *str_p; if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if (! dmalloc_verify_pnt(file, line, func, str, 0 /* not exact */, -1)) { dmalloc_message("bad pointer argument found in %s", func); } } for (str_p = str; *str_p != '\0'; str_p++) { len++; } return len; }
/* * static void *heap_extend * * DESCRIPTION: * * Get more bytes from the system functions. * * RETURNS: * * Success - Valid pointer. * * Failure - NULL * * ARGUMENTS: * * incr -> Number of bytes we need. */ static void *heap_extend(const int incr) { void *ret = SBRK_ERROR; char *high; #if INTERNAL_MEMORY_SPACE { static char block_o_bytes[INTERNAL_MEMORY_SPACE]; static char *bounds_p = block_o_bytes + sizeof(block_o_bytes); static char *block_p = block_o_bytes; if (block_p + incr >= bounds_p) { ret = SBRK_ERROR; } else { ret = block_p; block_p += incr; } } #else #if HAVE_MMAP && USE_MMAP #if MAP_ANON /* if we have and can use mmap, then do so */ ret = mmap(0L, incr, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1 /* no fd */, 0 /* no offset */); #else #endif if (ret == MAP_FAILED) { ret = SBRK_ERROR; } #else #if HAVE_SBRK ret = sbrk(incr); #endif /* if HAVE_SBRK */ #endif /* if not HAVE_MMAP && USE_MMAP */ #endif /* if not INTERNAL_MEMORY_SPACE */ if (ret == SBRK_ERROR) { if (BIT_IS_SET(_dmalloc_flags, DEBUG_CATCH_NULL)) { char str[128]; int len; len = loc_snprintf(str, sizeof(str), "\r\ndmalloc: critical error: could not extend heap %u more bytes\r\n", incr); (void)write(STDERR, str, len); _dmalloc_die(0); } dmalloc_errno = ERROR_ALLOC_FAILED; dmalloc_error("heap_extend"); } if (_dmalloc_heap_low == NULL || (char *)ret < (char *)_dmalloc_heap_low) { _dmalloc_heap_low = ret; } high = (char *)ret + incr; if (high > (char *)_dmalloc_heap_high) { _dmalloc_heap_high = high; } if (BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_ADMIN)) { dmalloc_message("extended heap space by %d bytes [%#lx, %#lx]", incr, (unsigned long)_dmalloc_heap_low, (unsigned long)_dmalloc_heap_high); } return ret; }
/* * void _dmalloc_open_log * * DESCRIPTION: * * Open up our log file and write some version of settings * information. * * RETURNS: * * None. * * ARGUMENTS: * * None. */ void _dmalloc_open_log(void) { char log_path[1024]; int len; /* if it's already open or if we don't have a log file configured */ if (outfile_fd >= 0 || dmalloc_logpath == NULL) { return; } build_logfile_path(log_path, sizeof(log_path)); /* open our logfile */ outfile_fd = open(log_path, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (outfile_fd < 0) { /* NOTE: we can't use dmalloc_message of course so do it the hardway */ len = loc_snprintf(error_str, sizeof(error_str), "debug-malloc library: could not open '%s'\r\n", log_path); (void)write(STDERR, error_str, len); /* disable log_path */ dmalloc_logpath = NULL; return; } /* * NOTE: this makes it go recursive here, but it will never enter * this section of code. */ dmalloc_message("Dmalloc version '%s' from '%s'", dmalloc_version, DMALLOC_HOME); dmalloc_message("flags = %#x, logfile '%s'", _dmalloc_flags, log_path); dmalloc_message("interval = %lu, addr = %#lx, seen # = %ld, limit = %ld", _dmalloc_check_interval, (unsigned long)_dmalloc_address, _dmalloc_address_seen_n, _dmalloc_memory_limit); #if LOCK_THREADS dmalloc_message("threads enabled, lock-on = %d, lock-init = %d", _dmalloc_lock_on, THREAD_INIT_LOCK); #endif #if LOG_PNT_TIMEVAL { char time_buf[64]; dmalloc_message("starting time = %s", _dmalloc_ptimeval(&_dmalloc_start, time_buf, sizeof(time_buf), 0)); } #else #if HAVE_TIME /* NOT LOG_PNT_TIME */ { char time_buf[64]; dmalloc_message("starting time = %s", _dmalloc_ptime(&_dmalloc_start, time_buf, sizeof(time_buf), 0)); } #endif #endif #if HAVE_GETPID { /* we make it long in case it's big and we hope it will promote if not */ long our_pid = getpid(); dmalloc_message("process pid = %ld", our_pid); } #endif }
int handle_command(char *buffer) { int rc = 1; char *op; int cmdtype; static unsigned long mark; if (ExtractArg(buffer, &op, &buffer) < 0) { return -1; } cmdtype = type_command(op); switch (cmdtype) { case COMMAND_GET: handle_get_command(buffer); break; case COMMAND_SET: handle_set_command(buffer); break; case COMMAND_RESET: handle_reset_command(buffer); break; case COMMAND_BYE: handle_bye_command(buffer); rc = 0; break; case COMMAND_CLI: handle_cli_command(buffer); break; case COMMAND_MEMSTART: #ifdef _DMALLOC_ dmalloc_message("starting new log"); mark = dmalloc_mark(); #elif _DBMALLOC_ if(malloc_chain_check(0)!=0) { int fd; fd = open("/usr/local/nextone/logs/malloc.inuse", O_CREAT|O_RDWR ); malloc_dump(fd ); close(fd); } orig_size = malloc_inuse(&histid1); #endif break; case COMMAND_MEMSTOP: #ifdef _DMALLOC_ dmalloc_log_changed(mark, 1, 0, 1); dmalloc_message("end of log"); #elif _DBMALLOC_ current_size = malloc_inuse(&histid2); if(current_size != orig_size) { int fd; fd = open("/usr/local/nextone/logs/malloc.inuse", O_CREAT|O_RDWR ); malloc_list(fd, histid1, histid2); close(fd); } #endif break; case COMMAND_NONE: default: break; } return rc; }