diff options
Diffstat (limited to 'epan/emem.c')
-rw-r--r-- | epan/emem.c | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/epan/emem.c b/epan/emem.c index 1076f8f842..fb38d75532 100644 --- a/epan/emem.c +++ b/epan/emem.c @@ -152,7 +152,12 @@ typedef struct _emem_header_t { } emem_header_t; -static emem_header_t ep_packet_mem; +static GSList *ep_pool_stack = NULL; +/* Some functions use ep_ calls when there isn't actually a packet in scope. + * These should perhaps be fixed, but in the meantime, ep_fake_pool is used + * to handle those cases. */ +static emem_header_t ep_fake_pool; +static emem_header_t *ep_packet_mem = &ep_fake_pool; static emem_header_t se_packet_mem; /* @@ -259,11 +264,11 @@ ep_check_canary_integrity(const char* fmt, ...) g_vsnprintf(here, sizeof(here), fmt, ap); va_end(ap); - for (npc = ep_packet_mem.free_list; npc != NULL; npc = npc->next) { + for (npc = ep_packet_mem->free_list; npc != NULL; npc = npc->next) { void *canary_next = npc->canary_last; while (canary_next != NULL) { - canary_next = emem_canary_next(ep_packet_mem.canary, canary_next, NULL); + canary_next = emem_canary_next(ep_packet_mem->canary, canary_next, NULL); /* XXX, check if canary_next is inside allocated memory? */ if (canary_next == (void *) -1) @@ -293,21 +298,21 @@ emem_init_chunk(emem_header_t *mem) * up. */ static void -ep_init_chunk(void) +ep_init_chunk(emem_header_t *mem) { - ep_packet_mem.free_list=NULL; - ep_packet_mem.used_list=NULL; - ep_packet_mem.trees=NULL; /* not used by this allocator */ + mem->free_list=NULL; + mem->used_list=NULL; + mem->trees=NULL; /* not used by this allocator */ - ep_packet_mem.debug_use_chunks = (getenv("WIRESHARK_DEBUG_EP_NO_CHUNKS") == NULL); - ep_packet_mem.debug_use_canary = ep_packet_mem.debug_use_chunks && (getenv("WIRESHARK_DEBUG_EP_NO_CANARY") == NULL); - ep_packet_mem.debug_verify_pointers = (getenv("WIRESHARK_EP_VERIFY_POINTERS") != NULL); + mem->debug_use_chunks = (getenv("WIRESHARK_DEBUG_EP_NO_CHUNKS") == NULL); + mem->debug_use_canary = mem->debug_use_chunks && (getenv("WIRESHARK_DEBUG_EP_NO_CANARY") == NULL); + mem->debug_verify_pointers = (getenv("WIRESHARK_EP_VERIFY_POINTERS") != NULL); #ifdef DEBUG_INTENSE_CANARY_CHECKS intense_canary_checking = (getenv("WIRESHARK_DEBUG_EP_INTENSE_CANARY") != NULL); #endif - emem_init_chunk(&ep_packet_mem); + emem_init_chunk(mem); } /* Initialize the capture-lifetime memory allocation pool. @@ -335,8 +340,8 @@ se_init_chunk(void) void emem_init(void) { - ep_init_chunk(); se_init_chunk(); + ep_init_chunk(&ep_fake_pool); if (getenv("WIRESHARK_DEBUG_SCRUB_MEMORY")) debug_use_memory_scrubber = TRUE; @@ -387,21 +392,21 @@ print_alloc_stats() fprintf(stderr, "\n-------- EP allocator statistics --------\n"); fprintf(stderr, "%s chunks, %s canaries, %s memory scrubber\n", - ep_packet_mem.debug_use_chunks ? "Using" : "Not using", - ep_packet_mem.debug_use_canary ? "using" : "not using", + ep_packet_mem->debug_use_chunks ? "Using" : "Not using", + ep_packet_mem->debug_use_canary ? "using" : "not using", debug_use_memory_scrubber ? "using" : "not using"); - if (! (ep_packet_mem.free_list || !ep_packet_mem.used_list)) { + if (! (ep_packet_mem->free_list || !ep_packet_mem->used_list)) { fprintf(stderr, "No memory allocated\n"); ep_stat = FALSE; } - if (ep_packet_mem.debug_use_chunks && ep_stat) { + if (ep_packet_mem->debug_use_chunks && ep_stat) { /* Nothing interesting without chunks */ /* Only look at the used_list since those chunks are fully * used. Looking at the free list would skew our view of what * we have wasted. */ - for (chunk = ep_packet_mem.used_list; chunk; chunk = chunk->next) { + for (chunk = ep_packet_mem->used_list; chunk; chunk = chunk->next) { num_chunks++; total_used += (chunk->amount_free_init - chunk->amount_free); total_allocation += chunk->amount_free_init; @@ -555,8 +560,8 @@ emem_verify_pointer(const emem_header_t *hdr, const void *ptr) gboolean ep_verify_pointer(const void *ptr) { - if (ep_packet_mem.debug_verify_pointers) - return emem_verify_pointer(&ep_packet_mem, ptr); + if (ep_packet_mem->debug_verify_pointers) + return emem_verify_pointer(ep_packet_mem, ptr); else return FALSE; } @@ -864,7 +869,7 @@ emem_alloc(size_t size, emem_header_t *mem) void * ep_alloc(size_t size) { - return emem_alloc(size, &ep_packet_mem); + return emem_alloc(size, ep_packet_mem); } /* allocate 'size' amount of memory with an allocation lifetime until the @@ -1237,11 +1242,39 @@ emem_free_all(emem_header_t *mem) } } -/* release all allocated memory back to the pool. */ -void -ep_free_all(void) +emem_header_t *ep_create_pool(void) +{ + emem_header_t *mem; + + mem = g_malloc(sizeof(emem_header_t)); + + ep_init_chunk(mem); + + if (ep_pool_stack == NULL) { + emem_free_all(&ep_fake_pool); + } + + ep_pool_stack = g_slist_prepend(ep_pool_stack, mem); + + ep_packet_mem = mem; + + return mem; +} + +void ep_free_pool(emem_header_t *mem) { - emem_free_all(&ep_packet_mem); + ep_pool_stack = g_slist_remove(ep_pool_stack, mem); + + emem_free_all(mem); + + g_free(mem); + + if (ep_pool_stack == NULL) { + ep_packet_mem = &ep_fake_pool; + } + else { + ep_packet_mem = ep_pool_stack->data; + } } /* release all allocated memory back to the pool. */ |