summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport/src/malloc_boundary.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2007-12-18 20:36:40 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2007-12-18 20:36:40 +0000
commit543fe820616f31350366ab61052050303d17dd25 (patch)
treea2e4702be2cd9988ed341586c1c8c976b8ba3bb8 /cpukit/libcsupport/src/malloc_boundary.c
parent2007-12-18 Joel Sherrill <joel.sherrill@OARcorp.com> (diff)
downloadrtems-543fe820616f31350366ab61052050303d17dd25.tar.bz2
2007-12-18 Joel Sherrill <joel.sherrill@oarcorp.com>
* libcsupport/Makefile.am, libcsupport/preinstall.am, libcsupport/src/malloc.c, libcsupport/src/mallocinfo.c, libmisc/Makefile.am, libmisc/shell/main_mallocinfo.c, libmisc/shell/shellconfig.h: Split malloc.c into multiple files with one function per file. Also split out statistics into a separate file which can be plugged in dynamically. Right now, it is always in. I suspect that splitting the file removed more code than leaving statistics in. I tinkered with malloc information command in the shell. I resurrected the malloc arena code as malloc boundary. This code is now compiled all the time even though it does not appear to work. * libcsupport/include/rtems/malloc.h, libcsupport/src/_calloc_r.c, libcsupport/src/_free_r.c, libcsupport/src/_malloc_r.c, libcsupport/src/_realloc_r.c, libcsupport/src/calloc.c, libcsupport/src/free.c, libcsupport/src/malloc_boundary.c, libcsupport/src/malloc_get_statistics.c, libcsupport/src/malloc_initialize.c, libcsupport/src/malloc_p.h, libcsupport/src/malloc_report_statistics.c, libcsupport/src/malloc_report_statistics_plugin.c, libcsupport/src/malloc_statistics_helpers.c, libcsupport/src/malloc_walk.c, libcsupport/src/realloc.c, libmisc/shell/main_perioduse.c: New files.
Diffstat (limited to 'cpukit/libcsupport/src/malloc_boundary.c')
-rw-r--r--cpukit/libcsupport/src/malloc_boundary.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/cpukit/libcsupport/src/malloc_boundary.c b/cpukit/libcsupport/src/malloc_boundary.c
new file mode 100644
index 0000000000..706e224294
--- /dev/null
+++ b/cpukit/libcsupport/src/malloc_boundary.c
@@ -0,0 +1,194 @@
+/*
+ * RTEMS Malloc Block Boundary Integrity Checker
+ *
+ * WARNING!!! WARNING!!! WARNING!!! WARNING!!!
+ * WARNING!!! WARNING!!! WARNING!!! WARNING!!!
+ *
+ * This file is built but never called. It is a first
+ * step in reintegrating this functionality.
+ * This code was disabled for a LONG time in malloc.c.
+ * This is a restructured and slightly modified version
+ * that should be able to be configured as a plugin BUT
+ * it has not been tested recently. When it has been
+ * tested again, please remove this comment.
+ *
+ * JOEL: I have not analyzed this code in terms of
+ * the heap changes post 4.6. It is possible
+ * that that way the boundary area is carved
+ * off breaks the alignment.
+ *
+ * WARNING!!! WARNING!!! WARNING!!! WARNING!!!
+ * WARNING!!! WARNING!!! WARNING!!! WARNING!!!
+ *
+ * COPYRIGHT (c) 1989-2007.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "malloc_p.h"
+
+#include <stdio.h>
+
+#ifdef RTEMS_NEWLIB
+
+#define SENTINELSIZE 12
+#define SENTINEL "\xD1\xAC\xB2\xF1" "BITE ME"
+#define CALLCHAINSIZE 5
+
+struct mallocNode {
+ struct mallocNode *back;
+ struct mallocNode *forw;
+ int callChain[CALLCHAINSIZE];
+ size_t size;
+ void *memory;
+};
+
+struct mallocNode mallocNodeHead;
+
+void rtems_malloc_boundary_initialize(void)
+{
+ mallocNodeHead.back = &mallocNodeHead;
+ mallocNodeHead.forw = &mallocNodeHead;
+}
+
+uint32_t rtems_malloc_boundary_overhead(void)
+{
+ return sizeof(struct mallocNode) + SENTINELSIZE;
+}
+
+void rtems_malloc_boundary_at_malloc(
+ void *pointer,
+ size_t size
+)
+{
+ void *return_this;
+ struct mallocNode *mp = (struct mallocNode *)pointer;
+ int *fp, *nfp, i;
+
+ _RTEMS_Lock_allocator();
+ mp->memory = mp + 1;
+ return_this = mp->memory;
+ mp->size = size - (sizeof(struct mallocNode) + SENTINELSIZE);
+ fp = (int *)&size - 2;
+ for (i = 0 ; i < CALLCHAINSIZE ; i++) {
+ mp->callChain[i] = fp[1];
+ nfp = (int *)(fp[0]);
+ if((nfp <= fp) || (nfp > (int *)(1 << 24)))
+ break;
+ fp = nfp;
+ }
+ while (i < CALLCHAINSIZE)
+ mp->callChain[i++] = 0;
+ memcpy((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE);
+ mp->forw = mallocNodeHead.forw;
+ mp->back = &mallocNodeHead;
+ mallocNodeHead.forw->back = mp;
+ mallocNodeHead.forw = mp;
+ _RTEMS_Unlock_allocator();
+}
+
+void reportMallocError(const char *msg, struct mallocNode *mp);
+
+void rtems_malloc_boundary_at_free(
+ void *pointer
+)
+{
+ struct mallocNode *mp = (struct mallocNode *)pointer - 1;
+ struct mallocNode *mp1;
+
+ _RTEMS_Lock_allocator();
+ if ((mp->memory != (mp + 1)) ||
+ (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0))
+ reportMallocError("Freeing with inconsistent pointer/sentinel", mp);
+ mp1 = mallocNodeHead.forw;
+ while (mp1 != &mallocNodeHead) {
+ if (mp1 == mp)
+ break;
+ mp1 = mp1->forw;
+ }
+ if (mp1 != mp)
+ reportMallocError("Freeing, but not on allocated list", mp);
+ mp->forw->back = mp->back;
+ mp->back->forw = mp->forw;
+ mp->back = mp->forw = NULL;
+ pointer = mp;
+ _RTEMS_Unlock_allocator();
+}
+
+void rtems_malloc_boundary_at_realloc(
+ void *pointer,
+ size_t size
+)
+{
+ /* this needs to be implemented */
+}
+
+/*
+ * Malloc boundary support plugin
+ */
+rtems_malloc_boundary_functions_t rtems_malloc_boundary_functions_table = {
+ rtems_malloc_boundary_initialize,
+ rtems_malloc_boundary_overhead,
+ rtems_malloc_boundary_at_malloc,
+ rtems_malloc_boundary_at_free,
+ rtems_malloc_boundary_at_realloc,
+};
+
+rtems_malloc_boundary_functions_t *rtems_malloc_boundary_helpers = NULL;
+/* &rtems_malloc_boundary_functions_table; */
+
+void reportMallocError(const char *msg, struct mallocNode *mp)
+{
+ unsigned char *sp = (unsigned char *)mp->memory + mp->size;
+ int i, ind = 0;
+ static char cbuf[500];
+ ind += sprintf(cbuf+ind, "Malloc Error: %s\n", msg);
+ if ((mp->forw->back != mp) || (mp->back->forw != mp))
+ ind += sprintf(cbuf+ind,
+ "mp:%p mp->forw:%p mp->forw->back:%p "
+ "mp->back:%p mp->back->forw:%p\n",
+ mp, mp->forw, mp->forw->back, mp->back, mp->back->forw);
+ if (mp->memory != (mp + 1))
+ ind += sprintf(cbuf+ind, "mp+1:%p ", mp + 1);
+ ind += sprintf(cbuf+ind, "mp->memory:%p mp->size:%d\n", mp->memory, mp->size);
+ if (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0) {
+ ind += sprintf(cbuf+ind, "mp->sentinel: ");
+ for (i = 0 ; i < SENTINELSIZE ; i++)
+ ind += sprintf(cbuf+ind, " 0x%x", sp[i]);
+ ind += sprintf(cbuf+ind, "\n");
+ }
+ ind += sprintf(cbuf+ind, "Call chain:");
+ for (i = 0 ; i < CALLCHAINSIZE ; i++) {
+ if (mp->callChain[i] == 0)
+ break;
+ ind += sprintf(cbuf+ind, " 0x%x", mp->callChain[i]);
+ }
+ printk("\n\n%s\n\n", cbuf);
+}
+
+void checkMallocArena(void)
+{
+ struct mallocNode *mp;
+
+ _RTEMS_Lock_allocator();
+ for ( mp = mallocNodeHead.forw; mp != &mallocNodeHead ; mp = mp->forw ) {
+ if ((mp->forw->back != mp) || (mp->back->forw != mp))
+ reportMallocError("Pointers mangled", mp);
+ if ((mp->memory != (mp + 1)) ||
+ (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0))
+ reportMallocError("Inconsistent pointer/sentinel", mp);
+ }
+ _RTEMS_Unlock_allocator();
+}
+
+#endif
+