From 99ce4232cbd440daf89aed3fd98f7f93645c500e Mon Sep 17 00:00:00 2001 From: Jeff Morriss Date: Wed, 16 Jan 2013 03:34:29 +0000 Subject: [PATCH] As suggested in comments in sl_alloc() and sl_free(): add a new environment variable (WIRESHARK_DEBUG_USE_SLICES) which turns off the slab allocator and uses g_slices instead (which can themselves be turned off by setting G_SLICE=always-malloc). This makes debugging problems in slab-allocated memory easier to find (hopefully including https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8197 ). Set WIRESHARK_DEBUG_USE_SLICES when running Valgrind on *shark. Remove unused structure member: emem_chunk_t.org. svn path=/trunk/; revision=47110 --- doc/rawshark.pod | 6 ++++++ doc/tshark.pod | 6 ++++++ doc/wireshark.pod.template | 6 ++++++ epan/emem.c | 26 +++++++++++++++++++------- tools/valgrind-wireshark.sh | 1 + 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/doc/rawshark.pod b/doc/rawshark.pod index 69be6aba0d..dcc4dd7902 100644 --- a/doc/rawshark.pod +++ b/doc/rawshark.pod @@ -432,6 +432,12 @@ per-file memory is initialized to 0xBADDCAFE when the memory is allocated and is reset to 0xDEADBEEF when the memory is freed. This functionality is useful mainly to developers looking for bugs in the way memory is handled. +=item WIRESHARK_DEBUG_USE_SLICES + +Exporting this environment variable causes slab allocations to be done using +glib's g_slice routines. This, combined with glib's G_SLICE=always-malloc +setting, can help developers looking for bugs in the way memory is handled. + =item WIRESHARK_RUN_FROM_BUILD_DIRECTORY This environment variable causes the plugins and other data files to be loaded diff --git a/doc/tshark.pod b/doc/tshark.pod index 961ef0102f..d47d43417c 100644 --- a/doc/tshark.pod +++ b/doc/tshark.pod @@ -1547,6 +1547,12 @@ per-file memory is initialized to 0xBADDCAFE when the memory is allocated and is reset to 0xDEADBEEF when the memory is freed. This functionality is useful mainly to developers looking for bugs in the way memory is handled. +=item WIRESHARK_DEBUG_USE_SLICES + +Exporting this environment variable causes slab allocations to be done using +glib's g_slice routines. This, combined with glib's G_SLICE=always-malloc +setting, can help developers looking for bugs in the way memory is handled. + =item WIRESHARK_RUN_FROM_BUILD_DIRECTORY This environment variable causes the plugins and other data files to be loaded diff --git a/doc/wireshark.pod.template b/doc/wireshark.pod.template index 96f19e03a5..fa3a8dadac 100644 --- a/doc/wireshark.pod.template +++ b/doc/wireshark.pod.template @@ -2735,6 +2735,12 @@ per-file memory is initialized to 0xBADDCAFE when the memory is allocated and is reset to 0xDEADBEEF when the memory is freed. This functionality is useful mainly to developers looking for bugs in the way memory is handled. +=item WIRESHARK_DEBUG_USE_SLICES + +Exporting this environment variable causes slab allocations to be done using +glib's g_slice routines. This, combined with glib's G_SLICE=always-malloc +setting, can help developers looking for bugs in the way memory is handled. + =item WIRESHARK_RUN_FROM_BUILD_DIRECTORY This environment variable causes the plugins and other data files to be loaded diff --git a/epan/emem.c b/epan/emem.c index a3c9585c6d..9e17f558fb 100644 --- a/epan/emem.c +++ b/epan/emem.c @@ -112,7 +112,6 @@ static int dev_zero_fd; typedef struct _emem_chunk_t { struct _emem_chunk_t *next; char *buf; - char *org; size_t size; unsigned int amount_free_init; unsigned int amount_free; @@ -171,6 +170,14 @@ static emem_pool_t se_packet_mem; */ static gboolean debug_use_memory_scrubber = FALSE; +/* + * Use g_slices in the slab allocator; enabling this (by putting + * WIRESHARK_DEBUG_USE_SLICES in the environment) together with + * exporting G_SLICE=always-malloc makes it easier to debug memory problems + * in slab-allocated memory. + */ +static gboolean debug_use_slices = FALSE; + #if defined (_WIN32) static SYSTEM_INFO sysinfo; static OSVERSIONINFO versinfo; @@ -349,6 +356,9 @@ emem_init(void) if (getenv("WIRESHARK_DEBUG_SCRUB_MEMORY")) debug_use_memory_scrubber = TRUE; + if (getenv("WIRESHARK_DEBUG_USE_SLICES")) + debug_use_slices = TRUE; + #if defined (_WIN32) /* Set up our guard page info for Win32 */ GetSystemInfo(&sysinfo); @@ -367,7 +377,7 @@ emem_init(void) #elif defined(USE_GUARD_PAGES) pagesize = sysconf(_SC_PAGESIZE); - if (pagesize == -1) + if (pagesize == -1) fprintf(stderr, "Warning: call to sysconf() for _SC_PAGESIZE has failed...\n"); #ifdef NEED_DEV_ZERO dev_zero_fd = ws_open("/dev/zero", O_RDWR); @@ -686,9 +696,9 @@ emem_destroy_chunk(emem_chunk_t *npc) /* we cannot recover from a munmap() failure, but we */ /* can print an informative error message to stderr */ - if (munmap(npc->buf, npc->amount_free_init) != 0) + if (munmap(npc->buf, npc->amount_free_init) != 0) fprintf(stderr, "Warning: Unable to unmap memory chunk which has address %p and size %u\n", - npc->buf, npc->amount_free_init); + npc->buf, npc->amount_free_init); #else g_free(npc->buf); #endif @@ -898,7 +908,8 @@ sl_alloc(struct ws_memory_slab *mem_chunk) emem_chunk_t *chunk; void *ptr; - /* XXX, debug_use_slices -> fallback to g_slice_alloc0 */ + if (debug_use_slices) + return g_slice_alloc0(mem_chunk->item_size); if ((mem_chunk->freed != NULL)) { ptr = mem_chunk->freed; @@ -929,8 +940,9 @@ sl_alloc(struct ws_memory_slab *mem_chunk) void sl_free(struct ws_memory_slab *mem_chunk, gpointer ptr) { - /* XXX, debug_use_slices -> fallback to g_slice_free1 */ - + if (debug_use_slices) { + g_slice_free1(mem_chunk->item_size, ptr); + } else /* XXX, abort if ptr not found in emem_verify_pointer_list()? */ if (ptr != NULL /* && emem_verify_pointer_list(mem_chunk->chunk_list, ptr) */) { memcpy(ptr, &(mem_chunk->freed), sizeof(void *)); diff --git a/tools/valgrind-wireshark.sh b/tools/valgrind-wireshark.sh index c941ed39f6..462b0c1dca 100755 --- a/tools/valgrind-wireshark.sh +++ b/tools/valgrind-wireshark.sh @@ -79,6 +79,7 @@ fi export WIRESHARK_DEBUG_EP_NO_CHUNKS= export WIRESHARK_DEBUG_SE_NO_CHUNKS= export WIRESHARK_DEBUG_WMEM_OVERRIDE=simple +export WIRESHARK_DEBUG_USE_SLICES= export G_SLICE=always-malloc # or debug-blocks libtool --mode=execute valgrind $LEAK_CHECK $REACHABLE $TRACK_ORIGINS $BIN_DIR/$COMMAND $COMMAND_ARGS $PCAP $COMMAND_ARGS2 > /dev/null