aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2012-12-28 17:04:23 +0000
committerEvan Huus <eapache@gmail.com>2012-12-28 17:04:23 +0000
commit0c66691b92668caaf51aac05a8c30f85867571db (patch)
tree6974bd38d86ef7872d29d860b8d94b110e725325 /epan
parent5588d07faae0f3f07ad18f2b3c8586528b28361b (diff)
Add a strict allocator that does canaries and various other things, for
platforms which don't have Valgrind. Valgrind is still the better choice on platforms which support it. svn path=/trunk/; revision=46828
Diffstat (limited to 'epan')
-rw-r--r--epan/CMakeLists.txt1
-rw-r--r--epan/wmem/Makefile.common2
-rw-r--r--epan/wmem/wmem_allocator_strict.c180
-rw-r--r--epan/wmem/wmem_allocator_strict.h58
-rw-r--r--epan/wmem/wmem_core.c7
-rw-r--r--epan/wmem/wmem_core.h3
6 files changed, 250 insertions, 1 deletions
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt
index d816b2103b..854c1aae29 100644
--- a/epan/CMakeLists.txt
+++ b/epan/CMakeLists.txt
@@ -1355,6 +1355,7 @@ set(WMEM_FILES
wmem/wmem_core.c
wmem/wmem_allocator_block.c
wmem/wmem_allocator_simple.c
+ wmem/wmem_allocator_strict.c
wmem/wmem_scopes.c
wmem/wmem_slab.c
wmem/wmem_slist.c
diff --git a/epan/wmem/Makefile.common b/epan/wmem/Makefile.common
index 0e8f719579..ee29d22b1d 100644
--- a/epan/wmem/Makefile.common
+++ b/epan/wmem/Makefile.common
@@ -27,6 +27,7 @@ LIBWMEM_SRC = \
wmem_core.c \
wmem_allocator_block.c \
wmem_allocator_simple.c \
+ wmem_allocator_strict.c \
wmem_scopes.c \
wmem_slab.c \
wmem_slist.c \
@@ -40,6 +41,7 @@ LIBWMEM_INCLUDES = \
wmem_allocator.h \
wmem_allocator_block.h \
wmem_allocator_simple.h \
+ wmem_allocator_strict.h \
wmem_scopes.h \
wmem_slab.h \
wmem_slist.h \
diff --git a/epan/wmem/wmem_allocator_strict.c b/epan/wmem/wmem_allocator_strict.c
new file mode 100644
index 0000000000..dff214d412
--- /dev/null
+++ b/epan/wmem/wmem_allocator_strict.c
@@ -0,0 +1,180 @@
+/* wmem_allocator_strict.c
+ * Wireshark Memory Manager Strict Allocator
+ * Copyright 2012, Evan Huus <eapache@gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <string.h>
+
+#include <glib.h>
+
+#include "wmem_core.h"
+#include "wmem_allocator.h"
+
+/* In this allocator, we do everything we can to catch invalid memory accesses.
+ * This includes using canaries (what Valgrind calls redzones) and
+ * filling allocated and freed memory with garbage. Valgrind is still the
+ * better tool on the platforms where it is available - use it instead if
+ * possible.
+ */
+
+#define WMEM_CANARY_SIZE 16
+#define WMEM_CANARY_VALUE 0x8E
+
+#define WMEM_PREFILL 0xA1
+#define WMEM_POSTFILL 0x1A
+
+typedef struct _wmem_strict_allocator_block_t {
+ /* Simple manual singly-linked list of allocations */
+ struct _wmem_strict_allocator_block_t *next;
+
+ /* Just the length of real_data, not counting the canaries */
+ gsize data_len;
+
+ guint8 *leading_canary;
+ guint8 *real_data;
+ guint8 *trailing_canary;
+} wmem_strict_allocator_block_t;
+
+typedef struct _wmem_strict_allocator_t {
+ wmem_strict_allocator_block_t *block_list;
+} wmem_strict_allocator_t;
+
+static void *
+wmem_strict_alloc(void *private_data, const size_t size)
+{
+ wmem_strict_allocator_t *allocator;
+ wmem_strict_allocator_block_t *block;
+
+ allocator = (wmem_strict_allocator_t*) private_data;
+
+ block = g_new(wmem_strict_allocator_block_t, 1);
+
+ block->data_len = size;
+ block->leading_canary = g_malloc(block->data_len + (2 * WMEM_CANARY_SIZE));
+ block->real_data = block->leading_canary + WMEM_CANARY_SIZE;
+ block->trailing_canary = block->real_data + block->data_len;
+ block->next = allocator->block_list;
+ allocator->block_list = block;
+
+ memset(block->leading_canary, WMEM_CANARY_VALUE, WMEM_CANARY_SIZE);
+ memset(block->real_data, WMEM_PREFILL, block->data_len);
+ memset(block->trailing_canary, WMEM_CANARY_VALUE, WMEM_CANARY_SIZE);
+
+ return block->real_data;
+}
+
+static void
+wmem_strict_real_check_canaries(wmem_strict_allocator_t *allocator)
+{
+ guint i;
+ wmem_strict_allocator_block_t *block;
+
+ block = allocator->block_list;
+
+ while (block) {
+ for (i=0; i<WMEM_CANARY_SIZE; i++) {
+ g_assert(block->leading_canary[i] == WMEM_CANARY_VALUE);
+ g_assert(block->trailing_canary[i] == WMEM_CANARY_VALUE);
+ }
+ block = block->next;
+ }
+}
+
+void
+wmem_strict_check_canaries(wmem_allocator_t *allocator)
+{
+ /* XXX: Should this be a g_assert() instead? This is more of a general API
+ * issue - should allocator-specific functions be safe to call with an
+ * allocator of the wrong type or not? And how should they interact with the
+ * WIRESHARK_DEBUG_WMEM_OVERRIDE environment variable? */
+ if (allocator->type != WMEM_ALLOCATOR_STRICT) {
+ return;
+ }
+
+ wmem_strict_real_check_canaries(allocator->private_data);
+}
+
+static void
+wmem_strict_free_all(void *private_data)
+{
+ wmem_strict_allocator_t *allocator;
+ wmem_strict_allocator_block_t *block, *tmp;
+
+ allocator = (wmem_strict_allocator_t*) private_data;
+
+ wmem_strict_real_check_canaries(allocator);
+
+ block = allocator->block_list;
+
+ while (block) {
+ memset(block->real_data, WMEM_POSTFILL, block->data_len);
+
+ g_free(block->leading_canary);
+
+ tmp = block;
+ block = block->next;
+ g_free(tmp);
+ }
+
+ allocator->block_list = NULL;
+}
+
+static void
+wmem_strict_allocator_destroy(wmem_allocator_t *allocator)
+{
+ g_free(allocator->private_data);
+ g_free(allocator);
+}
+
+wmem_allocator_t *
+wmem_strict_allocator_new(void)
+{
+ wmem_allocator_t *allocator;
+ wmem_strict_allocator_t *strict_allocator;
+
+ allocator = g_new(wmem_allocator_t, 1);
+ strict_allocator = g_new(wmem_strict_allocator_t, 1);
+
+ allocator->alloc = &wmem_strict_alloc;
+ allocator->free_all = &wmem_strict_free_all;
+ allocator->destroy = &wmem_strict_allocator_destroy;
+ allocator->private_data = (void*) strict_allocator;
+
+ strict_allocator->block_list = NULL;
+
+ return allocator;
+}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wmem/wmem_allocator_strict.h b/epan/wmem/wmem_allocator_strict.h
new file mode 100644
index 0000000000..c4eb1e4269
--- /dev/null
+++ b/epan/wmem/wmem_allocator_strict.h
@@ -0,0 +1,58 @@
+/* wmem_allocator_strict.h
+ * Definitions for the Wireshark Memory Manager Strict Allocator
+ * Copyright 2012, Evan Huus <eapache@gmail.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __WMEM_ALLOCATOR_STRICT_H__
+#define __WMEM_ALLOCATOR_STRICT_H__
+
+#include "wmem_core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+wmem_allocator_t *
+wmem_strict_allocator_new(void);
+
+void
+wmem_strict_check_canaries(wmem_allocator_t *allocator);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __WMEM_ALLOCATOR_STRICT_H__ */
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/wmem/wmem_core.c b/epan/wmem/wmem_core.c
index 5a05332c56..0311ce0a6d 100644
--- a/epan/wmem/wmem_core.c
+++ b/epan/wmem/wmem_core.c
@@ -32,6 +32,7 @@
#include "wmem_allocator.h"
#include "wmem_allocator_simple.h"
#include "wmem_allocator_block.h"
+#include "wmem_allocator_strict.h"
void *
wmem_alloc(wmem_allocator_t *allocator, const size_t size)
@@ -84,6 +85,9 @@ wmem_allocator_new(const wmem_allocator_type_t type)
else if (strncmp(override, "block", strlen("block")) == 0) {
real_type = WMEM_ALLOCATOR_BLOCK;
}
+ else if (strncmp(override, "strict", strlen("strict")) == 0) {
+ real_type = WMEM_ALLOCATOR_STRICT;
+ }
else {
g_warning("Unrecognized wmem override");
real_type = type;
@@ -96,6 +100,9 @@ wmem_allocator_new(const wmem_allocator_type_t type)
case WMEM_ALLOCATOR_BLOCK:
allocator = wmem_block_allocator_new();
break;
+ case WMEM_ALLOCATOR_STRICT:
+ allocator = wmem_strict_allocator_new();
+ break;
default:
g_assert_not_reached();
/* This is necessary to squelch MSVC errors; is there
diff --git a/epan/wmem/wmem_core.h b/epan/wmem/wmem_core.h
index a405b269ad..ad71591252 100644
--- a/epan/wmem/wmem_core.h
+++ b/epan/wmem/wmem_core.h
@@ -34,7 +34,8 @@ extern "C" {
typedef enum _wmem_allocator_type_t {
WMEM_ALLOCATOR_SIMPLE,
- WMEM_ALLOCATOR_BLOCK
+ WMEM_ALLOCATOR_BLOCK,
+ WMEM_ALLOCATOR_STRICT
} wmem_allocator_type_t;
struct _wmem_allocator_t;