summaryrefslogtreecommitdiff
path: root/innobase/mem
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-01-30 16:37:47 +0200
committerunknown <monty@hundin.mysql.fi>2002-01-30 16:37:47 +0200
commit85278245af45fc301dc7940bec9a3434003285a6 (patch)
tree3ca7f6fddbb9bdc0b635f243af69c6606924c3c2 /innobase/mem
parent9369764f2226e0e8cb9724bcdac256f45330ba67 (diff)
parent8a56717c4ce14aa7e36e04a8dc880dcc1311ea28 (diff)
downloadmariadb-git-85278245af45fc301dc7940bec9a3434003285a6.tar.gz
Merge from 3.23.48 tree
BitKeeper/etc/logging_ok: auto-union Docs/manual.texi: Auto merged innobase/dict/dict0dict.c: Auto merged innobase/include/srv0srv.h: Auto merged innobase/mem/mem0dbg.c: Auto merged innobase/os/os0file.c: Auto merged innobase/que/que0que.c: Auto merged innobase/rem/rem0rec.c: Auto merged innobase/row/row0sel.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/srv/srv0start.c: Auto merged innobase/sync/sync0arr.c: Auto merged innobase/trx/trx0trx.c: Auto merged innobase/trx/trx0undo.c: Auto merged myisam/mi_check.c: Auto merged mysql-test/t/join.test: Auto merged mysys/hash.c: Auto merged scripts/mysql_config.sh: Auto merged sql/ha_innodb.h: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/sql_acl.cc: Auto merged
Diffstat (limited to 'innobase/mem')
-rw-r--r--innobase/mem/mem0dbg.c94
-rw-r--r--innobase/mem/mem0mem.c42
2 files changed, 119 insertions, 17 deletions
diff --git a/innobase/mem/mem0dbg.c b/innobase/mem/mem0dbg.c
index 571674a506b..f94119b7f38 100644
--- a/innobase/mem/mem0dbg.c
+++ b/innobase/mem/mem0dbg.c
@@ -810,7 +810,7 @@ mem_validate_no_assert(void)
}
mutex_exit(&mem_hash_mutex);
-
+
return(error);
#else
@@ -834,3 +834,95 @@ mem_validate(void)
return(TRUE);
}
+
+/****************************************************************
+Tries to find neigboring memory allocation blocks and dumps to stderr
+the neighborhood of a given pointer. */
+
+void
+mem_analyze_corruption(
+/*===================*/
+ byte* ptr) /* in: pointer to place of possible corruption */
+{
+ byte* p;
+ ulint i;
+ ulint dist;
+
+ ut_sprintf_buf(srv_fatal_errbuf, ptr - 250, 500);
+ fprintf(stderr,
+ "InnoDB: Apparent memory corruption: mem dump %s\n", srv_fatal_errbuf);
+
+ fprintf(stderr,
+ "InnoDB: Scanning backward trying to find previous allocated mem blocks\n");
+
+ p = ptr;
+ dist = 0;
+
+ for (i = 0; i < 10; i++) {
+ for (;;) {
+ if (((ulint)p) % 4 == 0) {
+
+ if (*((ulint*)p) == MEM_BLOCK_MAGIC_N) {
+ fprintf(stderr,
+ "Mem block at - %lu, file %s, line %lu\n",
+ dist, p + sizeof(ulint),
+ *(ulint*)(p + 8 + sizeof(ulint)));
+
+ break;
+ }
+
+ if (*((ulint*)p) == MEM_FREED_BLOCK_MAGIC_N) {
+ fprintf(stderr,
+ "Freed mem block at - %lu, file %s, line %lu\n",
+ dist, p + sizeof(ulint),
+ *(ulint*)(p + 8 + sizeof(ulint)));
+
+ break;
+ }
+ }
+
+ p--;
+ dist++;
+ }
+
+ p--;
+ dist++;
+ }
+
+ fprintf(stderr,
+ "InnoDB: Scanning forward trying to find next allocated mem blocks\n");
+
+ p = ptr;
+ dist = 0;
+
+ for (i = 0; i < 10; i++) {
+ for (;;) {
+ if (((ulint)p) % 4 == 0) {
+
+ if (*((ulint*)p) == MEM_BLOCK_MAGIC_N) {
+ fprintf(stderr,
+ "Mem block at + %lu, file %s, line %lu\n",
+ dist, p + sizeof(ulint),
+ *(ulint*)(p + 8 + sizeof(ulint)));
+
+ break;
+ }
+
+ if (*((ulint*)p) == MEM_FREED_BLOCK_MAGIC_N) {
+ fprintf(stderr,
+ "Freed mem block at + %lu, file %s, line %lu\n",
+ dist, p + sizeof(ulint),
+ *(ulint*)(p + 8 + sizeof(ulint)));
+
+ break;
+ }
+ }
+
+ p++;
+ dist++;
+ }
+
+ p++;
+ dist++;
+ }
+}
diff --git a/innobase/mem/mem0mem.c b/innobase/mem/mem0mem.c
index 19a2c0d61a7..3e0a9c008f3 100644
--- a/innobase/mem/mem0mem.c
+++ b/innobase/mem/mem0mem.c
@@ -14,8 +14,9 @@ Created 6/9/1994 Heikki Tuuri
#include "mach0data.h"
#include "buf0buf.h"
-#include "mem0dbg.c"
#include "btr0sea.h"
+#include "srv0srv.h"
+#include "mem0dbg.c"
/*
THE MEMORY MANAGEMENT
@@ -49,7 +50,7 @@ of the blocks stay the same. An exception is, of course, the case
where the caller requests a memory buffer whose size is
bigger than the threshold. In that case a block big enough must
be allocated.
-
+
The heap is physically arranged so that if the current block
becomes full, a new block is allocated and always inserted in the
chain of blocks as the last block.
@@ -85,18 +86,12 @@ mem_alloc_func_noninline(
/*=====================*/
/* out, own: free storage, NULL if did not
succeed */
- ulint n /* in: desired number of bytes */
- #ifdef UNIV_MEM_DEBUG
- ,char* file_name, /* in: file name where created */
+ ulint n, /* in: desired number of bytes */
+ char* file_name, /* in: file name where created */
ulint line /* in: line where created */
- #endif
)
{
- return(mem_alloc_func(n
-#ifdef UNIV_MEM_DEBUG
- , file_name, line
-#endif
- ));
+ return(mem_alloc_func(n, file_name, line));
}
/*******************************************************************
@@ -113,8 +108,10 @@ mem_heap_create_block(
if init_block is not NULL, its size in bytes */
void* init_block, /* in: init block in fast create, type must be
MEM_HEAP_DYNAMIC */
- ulint type) /* in: type of heap: MEM_HEAP_DYNAMIC, or
+ ulint type, /* in: type of heap: MEM_HEAP_DYNAMIC, or
MEM_HEAP_BUFFER possibly ORed to MEM_HEAP_BTR_SEARCH */
+ char* file_name,/* in: file name where created */
+ ulint line) /* in: line where created */
{
mem_block_t* block;
ulint len;
@@ -122,6 +119,10 @@ mem_heap_create_block(
ut_ad((type == MEM_HEAP_DYNAMIC) || (type == MEM_HEAP_BUFFER)
|| (type == MEM_HEAP_BUFFER + MEM_HEAP_BTR_SEARCH));
+ if (heap && heap->magic_n != MEM_BLOCK_MAGIC_N) {
+ mem_analyze_corruption((byte*)heap);
+ }
+
/* In dynamic allocation, calculate the size: block header + data. */
if (init_block != NULL) {
@@ -164,7 +165,11 @@ mem_heap_create_block(
}
block->magic_n = MEM_BLOCK_MAGIC_N;
-
+ ut_memcpy(&(block->file_name), file_name + ut_strlen(file_name) - 7,
+ 7);
+ block->file_name[7]='\0';
+ block->line = line;
+
mem_block_set_len(block, len);
mem_block_set_type(block, type);
mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE);
@@ -223,8 +228,8 @@ mem_heap_add_block(
new_size = n;
}
- new_block = mem_heap_create_block(heap, new_size, NULL, heap->type);
-
+ new_block = mem_heap_create_block(heap, new_size, NULL, heap->type,
+ heap->file_name, heap->line);
if (new_block == NULL) {
return(NULL);
@@ -250,12 +255,17 @@ mem_heap_block_free(
ulint len;
ibool init_block;
+ if (block->magic_n != MEM_BLOCK_MAGIC_N) {
+ mem_analyze_corruption((byte*)block);
+ }
+
UT_LIST_REMOVE(list, heap->base, block);
type = heap->type;
len = block->len;
init_block = block->init_block;
-
+ block->magic_n = MEM_FREED_BLOCK_MAGIC_N;
+
#ifdef UNIV_MEM_DEBUG
/* In the debug version we set the memory to a random combination
of hex 0xDE and 0xAD. */