From ba3547c825889fd3ad24da4004e6d0bb5a50853c Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Wed, 22 Oct 2008 22:22:00 +0300 Subject: [PATCH] silcd: fixed memory leaks --- apps/silcd/idlist.c | 4 + apps/silcd/server.c | 19 +- lib/configure.ad | 2 + lib/silcske/silcske.c | 8 +- lib/silcutil/stacktrace.c | 393 ++++++++++++++++++++++++++++++++------ lib/silcutil/stacktrace.h | 13 +- 6 files changed, 366 insertions(+), 73 deletions(-) diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index 1c75d718..13093c09 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -55,7 +55,10 @@ void silc_idlist_del_data(void *entry) if (idata->hash) silc_hash_free(idata->hash); + if (idata->rekey) + silc_ske_free_rekey_material(idata->rekey); + idata->rekey = NULL; idata->hash = NULL; idata->public_key = NULL; } @@ -395,6 +398,7 @@ void silc_idlist_client_destructor(SilcIDCache cache, client); assert(!silc_hash_table_count(client->channels)); + silc_free(entry->name); silc_free(client->nickname); silc_free(client->servername); silc_free(client->username); diff --git a/apps/silcd/server.c b/apps/silcd/server.c index c2df082c..0e1cffb0 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -704,6 +704,7 @@ void silc_server_free(SilcServer server) silc_free(server->local_list); silc_free(server->global_list); silc_free(server->server_name); + silc_free(server->id); silc_free(server); silc_hmac_unregister_all(); @@ -1608,7 +1609,6 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, SilcConnAuth connauth; SilcCipher send_key, receive_key; SilcHmac hmac_send, hmac_receive; - SilcHash hash; server = entry->server; sconn = entry->data.sconn; @@ -1644,7 +1644,7 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, /* Set the keys into use. The data will be encrypted after this. */ if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key, - &hmac_send, &hmac_receive, &hash)) { + &hmac_send, &hmac_receive, NULL)) { silc_ske_free(ske); /* Try reconnecting if configuration wants it */ @@ -2686,9 +2686,11 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, idata->rekey = rekey; idata->public_key = silc_pkcs_public_key_copy(prop->public_key); pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len); - silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint); - - silc_hash_alloc(silc_hash_get_name(prop->hash), &idata->hash); + if (pk) { + silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint); + silc_free(pk); + } + idata->hash = hash; SILC_LOG_DEBUG(("Starting connection authentication")); server->stat.auth_attempts++; @@ -2911,7 +2913,7 @@ SILC_TASK_CALLBACK(silc_server_do_rekey) SILC_LOG_DEBUG(("Perform rekey, sock %p", sock)); /* Do not execute rekey with disabled connections */ - if (idata->status & SILC_IDLIST_STATUS_DISABLED) + if (idata->status & SILC_IDLIST_STATUS_DISABLED || !idata->rekey) return; /* If another protocol is active do not start rekey */ @@ -2975,6 +2977,11 @@ static void silc_server_rekey(SilcServer server, SilcPacketStream sock, SilcIDListData idata = silc_packet_get_context(sock); SilcSKE ske; + if (!idata->rekey) { + silc_packet_free(packet); + return; + } + SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p", idata->sconn->remote_host, idata->sconn->remote_port, SILC_CONNTYPE_STRING(idata->conn_type), sock)); diff --git a/lib/configure.ad b/lib/configure.ad index 9ff9f49a..6f381c7b 100644 --- a/lib/configure.ad +++ b/lib/configure.ad @@ -163,6 +163,8 @@ AC_ARG_ENABLE(stack-trace, yes) AC_MSG_RESULT(yes) AC_DEFINE([SILC_STACKTRACE], [], [SILC_STACKTRACE]) + CFLAGS="$CFLAGS -rdynamic" + PC_CFLAGS="$PC_CFLAGS -rdynamic" ;; *) AC_MSG_RESULT(no) diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index caf25796..bac8a5c4 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -182,15 +182,11 @@ static void silc_ske_skr_callback(SilcSKR repository, static SilcSKEStatus silc_ske_check_version(SilcSKE ske) { - SilcUInt32 r_software_version = 0; - char *r_software_string = NULL; - if (!ske->remote_version || !ske->version) return SILC_SKE_STATUS_BAD_VERSION; if (!silc_parse_version_string(ske->remote_version, NULL, NULL, - &r_software_version, - &r_software_string, NULL)) + NULL, NULL, NULL)) return SILC_SKE_STATUS_BAD_VERSION; return SILC_SKE_STATUS_OK; @@ -2419,7 +2415,7 @@ SilcAsyncOperation silc_ske_responder(SilcSKE ske, ske->timeout = params->timeout_secs ? params->timeout_secs : 30; if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED) ske->session_port = params->session_port; - ske->version = strdup(params->version); + ske->version = params->version; if (!ske->version) return NULL; ske->running = TRUE; diff --git a/lib/silcutil/stacktrace.c b/lib/silcutil/stacktrace.c index 9f335e44..85e5417f 100644 --- a/lib/silcutil/stacktrace.c +++ b/lib/silcutil/stacktrace.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2002, 2007 Pekka Riikonen + Copyright (C) 2002 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,14 +17,72 @@ */ +/* This file implements memory leak checker and basic memory corruption + and double free checker. It is multi-thread safe. It does the + following: + + o Tracks all memory allocations and report any unfreed memory at the + end of the program with backtrace where the memory was allocated. + + o Checks if a memory location has been freed already and abort the + program with the backtrace of the location of the double free. + + o Checks if a given pointer has been allocated at all and abort the + program with the backtrace where the invalid free was given. + + o Checks at the time of free if the memory was written out of bounds + (overflow) and abort with the backtrace of the free. The backtrace + might not help to find the overflow but at least it is detected. + By setting SILC_MALLOC_DUMP the memory is dummped to help and see + what it contains. + + o Can detect if the memory is read or written out of bounds (overflow) + and abort immediately the with the backtrace when the illegal access + occurs. This can be enabled by using SILC_MALLOC_PROTECT. + + The following environment variables can be used: + + SILC_MALLOC_NO_FREE + + When set to value 1, the program doesn't actually free any memory. + This provides more detailed information especially in case of double + free. If the location of the double free cannot be located, by + setting this variable the program will show where the memory was + originally allocated and freed. + + SILC_MALLOC_DUMP + + When set to value 1, in case of fatal error, dumps the memory location, + if possible. This can help see what the memory contains. + + SILC_MALLOC_PROTECT + + When set to value 1 each allocation will have an inaccesible memory + page following the allocated memory area. This will detect if the + the memory is accessed (read or write) beyond its boundaries. This + will help to identify the place where illegal memory access occurs. + + To work correctly this of course expects that code uses SILC memory + allocation and access routines. + +*/ + #include "silc.h" #ifdef SILC_STACKTRACE +#include +#include +#include +#include static void *st_blocks = NULL; static unsigned long st_blocks_count = 0; +static unsigned long st_num_malloc = 0; static SilcBool dump = FALSE; -static SilcBool malloc_check = FALSE; +static SilcBool no_free = FALSE; +static SilcBool dump_mem = FALSE; +static SilcUInt32 pg = 0; +static SilcMutex lock = NULL; #ifdef SILC_DEBUG #define SILC_ST_DEPTH 15 @@ -34,71 +92,207 @@ static SilcBool malloc_check = FALSE; /* Memory block with stack trace */ typedef struct SilcStBlockStruct { - unsigned int dumpped : 1; /* Block is dumpped */ - unsigned int depth : 8; /* Depth of stack trace */ - unsigned int line : 23; /* Allocation line in program */ - void *stack[SILC_ST_DEPTH]; /* Stack trace */ - const char *file; /* Allocation file in program */ - unsigned long size; /* Allocated memory size */ struct SilcStBlockStruct *next; struct SilcStBlockStruct *prev; + void *stack[SILC_ST_DEPTH]; /* Stack trace */ + const char *file; /* Allocation file in program */ + const char *free_file; /* Free file in program */ + SilcUInt32 size; /* Allocated memory size */ + SilcUInt16 line; /* Allocation line in program */ + SilcUInt16 free_line; /* Free line in program */ + SilcUInt16 depth; /* Depth of stack trace */ + SilcUInt16 dumpped; /* Block is dumpped */ + SilcUInt32 bound; /* Top bound */ } *SilcStBlock; -/* Get current frame pointer */ -#define SILC_ST_GET_FP(ret_fp) \ -do { \ - register void *cfp; \ - asm volatile ("movl %%ebp, %0" : "=r" (cfp)); \ - (ret_fp) = cfp; \ -} while(0); - -#define SILC_ST_GET_SIZE(size) ((size + sizeof(struct SilcStBlockStruct))) +#define SILC_ST_TOP_BOUND 0xfeed1977 +#define SILC_ST_BOTTOM_BOUND 0x9152beef +#define SILC_ST_GET_SIZE(size) ((size + sizeof(struct SilcStBlockStruct) + 4)) #define SILC_ST_GET_STACK(p) ((SilcStBlock)(((unsigned char *)p) - \ sizeof(struct SilcStBlockStruct))) #define SILC_ST_GET_PTR(p) (((unsigned char *)p) + \ sizeof(struct SilcStBlockStruct)) - -void silc_st_stacktrace(SilcStBlock stack) +#define SILC_ST_GET_BOUND(p, size) (SilcUInt32 *)(((unsigned char *)p) + \ + SILC_ST_GET_SIZE(size) - 4) + +#define SILC_ST_ALIGN(bytes, align) (((bytes) + (align - 1)) & ~(align - 1)) +#define SILC_ST_GET_SIZE_ALIGN(size, align) \ + SILC_ST_ALIGN(SILC_ST_GET_SIZE(size) - 4, align) +#define SILC_ST_GET_PTR_ALIGN(stack, align) \ + (((unsigned char *)stack) - (SILC_ST_GET_SIZE_ALIGN(stack->size, pg) - \ + SILC_ST_GET_SIZE(stack->size)) - 4) +#define SILC_ST_GET_STACK_ALIGN(p, size, align) \ + ((SilcStBlock)(((unsigned char *)p) + (SILC_ST_GET_SIZE_ALIGN(size, pg) - \ + SILC_ST_GET_SIZE(size)) + 4)) + +#define silc_hexdump(ptr, size, file) \ + silc_log_output_hexdump("", "", 0, ptr, size, "") + +void silc_st_abort(SilcStBlock stack, const char *file, int line, + char *fmt, ...) { - void *fp; + void *bt[SILC_ST_DEPTH]; + SilcUInt32 *bound; + va_list va; + int btc; + + va_start(va, fmt); + vfprintf(stderr, fmt, va); + va_end(va); + + fprintf(stderr, "----- BACKTRACE -----\n%s:%d:\n", file, line); + btc = backtrace(bt, SILC_ST_DEPTH); + backtrace_symbols_fd(bt, btc, 2); + + if (stack) { + fprintf(stderr, "----- MEMORY TRACE -----\n"); + if (stack->free_file) + fprintf(stderr, "Freed at: %s:%d\n", stack->free_file, + stack->free_line); + fprintf(stderr, "Originally allocated at:\n"); + fprintf(stderr, "%s:%d:\n", stack->file, stack->line); + backtrace_symbols_fd(stack->stack, stack->depth, 2); + fflush(stderr); + + if (dump_mem) { + fprintf(stderr, "----- MEMORY HEADER -----\n"); + fprintf(stderr, "Header length: %lu, total length %lu\n", + sizeof(struct SilcStBlockStruct), SILC_ST_GET_SIZE(stack->size)); + silc_hexdump((void *)stack, sizeof(struct SilcStBlockStruct), stderr); + fflush(stderr); + fprintf(stderr, "Header bound is: %p\n", + SILC_32_TO_PTR(stack->bound)); + if (stack->bound != SILC_ST_TOP_BOUND) { + fprintf(stderr, "Header bound should be: %p\n", + SILC_32_TO_PTR(SILC_ST_TOP_BOUND)); + fprintf(stderr, "MEMORY IS CORRUPTED (UNDERFLOW)!\n"); + } - if (!dump) { - atexit(silc_st_dump); - dump = TRUE; + fprintf(stderr, "----- USER MEMORY -----\n"); + fprintf(stderr, "Length: %d\n", stack->size); + silc_hexdump(((unsigned char *)stack) + + sizeof(struct SilcStBlockStruct), stack->size, stderr); + fflush(stderr); + + fprintf(stderr, "----- MEMORY FOOTER -----\n"); + bound = SILC_ST_GET_BOUND(stack, stack->size); + silc_hexdump((unsigned char *)bound, 4, stderr); + fprintf(stderr, "Footer bound is: %p\n", SILC_32_TO_PTR(*bound)); + if (*bound != SILC_ST_BOTTOM_BOUND) { + fprintf(stderr, "Footer bound should be: %p\n", + SILC_32_TO_PTR(SILC_ST_BOTTOM_BOUND)); + fprintf(stderr, "MEMORY IS CORRUPTED (OVERFLOW)!\n"); + } + } } - if (!malloc_check) { - /* Linux libc malloc check */ - setenv("MALLOC_CHECK_", "2", 1); + fflush(stderr); - /* NetBSD malloc check */ - setenv("MALLOC_OPTIONS", "AJ", 1); + abort(); +} - malloc_check = TRUE; - } +void silc_st_sigsegv(int sig, siginfo_t *si, void *context) +{ + SilcStBlock orig, stack = (SilcStBlock)si->si_addr; - /* Save the stack */ - SILC_ST_GET_FP(fp); - for (stack->depth = 0; fp; stack->depth++) { - if (stack->depth == SILC_ST_DEPTH) - break; + /* Make the page accessible again */ + mprotect(si->si_addr, pg, PROT_READ | PROT_WRITE); + + /* Get the original page from the violated page */ + orig = (SilcStBlock)(((unsigned char *)si->si_addr) - + SILC_ST_GET_SIZE_ALIGN(stack->size, pg)); + stack = SILC_ST_GET_STACK_ALIGN(orig, stack->size, pg); + + silc_st_abort(stack, __FILE__, __LINE__, + "SILC_MALLOC: access violation (overflow)\n"); +} + +void silc_st_stacktrace_init(void) +{ + const char *var; + + atexit(silc_st_dump); + dump = TRUE; + + var = getenv("SILC_MALLOC_NO_FREE"); + if (var && *var == '1') + no_free = TRUE; + + var = getenv("SILC_MALLOC_DUMP"); + if (var && *var == '1') + dump_mem = TRUE; + + var = getenv("SILC_MALLOC_PROTECT"); + if (var && *var == '1') { + struct sigaction sa; + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = silc_st_sigsegv; + sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); - /* Get program pointer and frame pointer from this frame */ - stack->stack[stack->depth] = *((void **)(((unsigned char *)fp) + 4)); - fp = *((void **)fp); +#if defined(_SC_PAGESIZE) + pg = sysconf(_SC_PAGESIZE); +#elif defined(_SC_PAGE_SIZE) + pg = sysconf(_SC_PAGE_SIZE); +#else + pg = getpagesize(); +#endif /* _SC_PAGESIZE */ } + + /* Linux libc malloc check */ + setenv("MALLOC_CHECK_", "3", 1); + + /* NetBSD malloc check */ + setenv("MALLOC_OPTIONS", "AJ", 1); + + silc_mutex_alloc(&lock); } void *silc_st_malloc(size_t size, const char *file, int line) { - SilcStBlock stack = (SilcStBlock)malloc(SILC_ST_GET_SIZE(size)); - assert(stack != NULL); + SilcStBlock stack; + + if (silc_unlikely(!dump)) + silc_st_stacktrace_init(); + + if (pg) { + unsigned char *ptr; + + if (posix_memalign((void *)&ptr, pg, + SILC_ST_GET_SIZE_ALIGN(size, pg) + pg)) + return NULL; + + /* The inaccessible page too will include the allocation information + so that we can get it when access violation occurs in that page. */ + stack = (SilcStBlock)(ptr + SILC_ST_GET_SIZE_ALIGN(size, pg)); + stack->size = size; + + /* Protect the page */ + if (mprotect(stack, pg, PROT_NONE)) + silc_st_abort(NULL, file, line, "SILC_MALLOC: mprotect() error: %s\n", + errno == ENOMEM ? "Cannot allocate memory. \nYour program " + "leaks memory, allocates too much or system \n" + "is out of memory. The SILC_MALLOC_PROTECT cannot " + "be used." : strerror(errno)); + + /* Get the accessible page */ + stack = SILC_ST_GET_STACK_ALIGN(ptr, size, pg); + } else { + stack = (SilcStBlock)malloc(SILC_ST_GET_SIZE(size)); + if (!stack) + return NULL; + } stack->dumpped = 0; stack->file = file; + stack->free_file = NULL; stack->line = line; stack->size = size; - silc_st_stacktrace(stack); + stack->bound = SILC_ST_TOP_BOUND; + stack->depth = backtrace(stack->stack, SILC_ST_DEPTH); + + silc_mutex_lock(lock); stack->next = st_blocks; stack->prev = NULL; @@ -106,6 +300,12 @@ void *silc_st_malloc(size_t size, const char *file, int line) ((SilcStBlock)st_blocks)->prev = stack; st_blocks = stack; st_blocks_count++; + st_num_malloc++; + + silc_mutex_unlock(lock); + + if (!pg) + *SILC_ST_GET_BOUND(stack, size) = SILC_ST_BOTTOM_BOUND; return SILC_ST_GET_PTR(stack); } @@ -113,7 +313,8 @@ void *silc_st_malloc(size_t size, const char *file, int line) void *silc_st_calloc(size_t items, size_t size, const char *file, int line) { void *addr = (void *)silc_st_malloc(items * size, file, line); - memset(addr, 0, items * size); + if (addr) + memset(addr, 0, items * size); return addr; } @@ -125,25 +326,63 @@ void *silc_st_realloc(void *ptr, size_t size, const char *file, int line) return silc_st_malloc(size, file, line); stack = SILC_ST_GET_STACK(ptr); - if (stack->size >= size) { + if (!pg && stack->size >= size) { + /* Must update footer when the size changes */ + if (stack->size != size) + *SILC_ST_GET_BOUND(stack, size) = SILC_ST_BOTTOM_BOUND; + stack->size = size; return ptr; } else { void *addr = (void *)silc_st_malloc(size, file, line); - memcpy(addr, ptr, stack->size); - silc_st_free(ptr, file, line); + if (addr) { + memcpy(addr, ptr, size > stack->size ? stack->size : size); + silc_st_free(ptr, file, line); + } return addr; } } void silc_st_free(void *ptr, const char *file, int line) { - SilcStBlock stack; + SilcStBlock stack, s; if (!ptr) return; + /* Check for double free */ + if (!memcmp((unsigned char *)ptr - sizeof(struct SilcStBlockStruct), + "\x47\x47\x47\x47", 4)) + silc_st_abort(no_free ? ptr - sizeof(struct SilcStBlockStruct) : NULL, + file, line, "SILC_MALLOC: double free: %p already freed\n", + ptr - sizeof(struct SilcStBlockStruct)); + stack = SILC_ST_GET_STACK(ptr); + + silc_mutex_lock(lock); + + /* Check if we have ever made this allocation */ + for (s = st_blocks; s; s = s->next) + if (s == stack) + break; + if (s == NULL) + silc_st_abort(NULL, file, line, + "SILC_MALLOC: %p was never allocated\n", stack); + + if (!pg) { + /* Check for underflow */ + if (stack->bound != SILC_ST_TOP_BOUND) + silc_st_abort(stack, file, line, + "SILC_MALLOC: %p was written out of bounds (underflow)\n", + stack); + + /* Check for overflow */ + if (*SILC_ST_GET_BOUND(stack, stack->size) != SILC_ST_BOTTOM_BOUND) + silc_st_abort(stack, file, line, + "SILC_MALLOC: %p was written out of bounds (overflow)\n", + stack); + } + if (stack->next) stack->next->prev = stack->prev; if (stack->prev) @@ -153,15 +392,35 @@ void silc_st_free(void *ptr, const char *file, int line) st_blocks_count--; - memset(stack, 'F', SILC_ST_GET_SIZE(stack->size)); - free(stack); + silc_mutex_unlock(lock); + + stack->free_file = file; + stack->free_line = line; + + if (no_free) { + memset(stack, 0x47, 8); + return; + } + + if (pg) { + ptr = SILC_ST_GET_PTR_ALIGN(stack, pg); + mprotect(ptr + SILC_ST_GET_SIZE_ALIGN(stack->size, pg), pg, + PROT_READ | PROT_WRITE); + memset(ptr, 0x47, SILC_ST_GET_SIZE_ALIGN(stack->size, pg)); + free(ptr); + } else { + memset(stack, 0x47, SILC_ST_GET_SIZE(stack->size)); + free(stack); + } } void *silc_st_memdup(const void *ptr, size_t size, const char *file, int line) { unsigned char *addr = (unsigned char *)silc_st_malloc(size + 1, file, line); - memcpy((void *)addr, ptr, size); - addr[size] = '\0'; + if (addr) { + memcpy((void *)addr, ptr, size); + addr[size] = '\0'; + } return (void *)addr; } @@ -170,15 +429,20 @@ void *silc_st_strdup(const char *string, const char *file, int line) return silc_st_memdup(string, strlen(string), file, line); } -/* Dumps the stack into file if there are leaks. The file can be read - with a special stacktrace tool. */ +/* Dumps the stack into file if there are leaks. */ void silc_st_dump(void) { SilcStBlock stack, s; unsigned long leaks = 0, blocks, bytes; FILE *fp = NULL; + char **syms, *cp; int i; + SilcMutex l; + + l = lock; + lock = NULL; + silc_mutex_free(l); for (stack = st_blocks; stack; stack = stack->next) { bytes = blocks = 0; @@ -194,6 +458,10 @@ void silc_st_dump(void) fp = stderr; } + /* Get symbol names */ + syms = backtrace_symbols(stack->stack, stack->depth); + + /* Find number of leaks and bytes leaked for this leak */ for (s = stack; s; s = s->next) { if (s->file == stack->file && s->line == stack->line && s->depth == stack->depth && @@ -206,10 +474,24 @@ void silc_st_dump(void) } if (blocks) { - fprintf(fp, "%s:%d: #blocks=%lu, bytes=%lu\n", + fprintf(fp, "%s:%d: #blocks=%lu, bytes=%lu\n", stack->file, stack->line, blocks, bytes); - for (i = 0; i < stack->depth; i++) - fprintf(fp, "\tpc=%p\n", stack->stack[i]); + for (i = 0; i < stack->depth; i++) { + if (syms) { + cp = syms[i]; + if (strchr(cp, '(')) + cp = strchr(cp, '(') + 1; + else if (strchr(cp, ' ')) + cp = strchr(cp, ' ') + 1; + if (strchr(cp, ')')) + *strchr(cp, ')') = ' '; + fprintf(fp, "\t%s\n", cp); + } else { + fprintf(fp, "\tpc=%p\n", stack->stack[i]); + } + } + fprintf(fp, "\n"); + free(syms); } } @@ -224,6 +506,7 @@ void silc_st_dump(void) "-----------------------------------------\n" "-----------------------------------------\n", leaks, st_blocks_count); + fprintf(stderr, "Number of allocations: %lu\n", st_num_malloc); } if (fp && fp != stderr) diff --git a/lib/silcutil/stacktrace.h b/lib/silcutil/stacktrace.h index bfe8ae03..ae148904 100644 --- a/lib/silcutil/stacktrace.h +++ b/lib/silcutil/stacktrace.h @@ -1,6 +1,6 @@ /* - stacktrace.h + stacktrace.h Author: Pekka Riikonen @@ -17,14 +17,14 @@ */ -#ifndef STACKTRACE_H -#define STACKTRACE_H +#ifndef MEMTRACE_H +#define MEMTRACE_H #ifndef SILCMEMORY_H #error "Do not include internal header file directly" #endif -#if defined(__GNUC__) && defined(__i386__) +#if defined(__GNUC__) #undef strdup #define silc_malloc(s) silc_st_malloc((s), __FILE__, __LINE__) @@ -32,6 +32,7 @@ #define silc_realloc(p, s) silc_st_realloc((p), (s), __FILE__, __LINE__) #define silc_free(p) silc_st_free((p), __FILE__, __LINE__) #define silc_memdup(p, s) silc_st_memdup((p), (s), __FILE__, __LINE__) +#define silc_strdup(s) silc_st_strdup((s), __FILE__, __LINE__) #define strdup(s) silc_st_strdup((s), __FILE__, __LINE__) void *silc_st_malloc(size_t size, const char *file, int line); @@ -44,6 +45,6 @@ void silc_st_dump(void); #else #error "memory allocation stack trace not supported on this platform" -#endif /* __GNUC__ && __i386__ */ +#endif /* __GNUC__ */ -#endif /* STACKTRACE_H */ +#endif /* MEMTRACE_H */ -- 2.24.0