On 30.04.2012 19:24, Vladimir 'φ-coder/phcoder' Serbinenko wrote: > On 30.04.2012 17:26, Bean wrote: >> Hi, >> >> While testing network function in efi mode, I've found several memory >> leak related to fragmentation, but there is still some memory problem >> that's very tricky to locate. For example, you can run testspeed on a >> large file several times in a row and it could show the memory error. >> Since network condition are very difficult to reproduce, I have to >> look at the source of this issue, memory allocation. Currently it has >> mm_debug option that could print out file and line number of each >> memory call, but it's quite useless since we can't find the relevant >> informaton with full screen of prints. >> Here are some of my ideas for enhanced memory protection support: >> >> 1, when we allocate memory, we append some information at the end of >> the buffer, which include filename, lineno of caller, and tag to >> indicate what is used for and some padding to detect memory overwrite >> problem. >> >> 2. add a command to print the current memory list with extended >> information, this can be used to find memory leaks. >> >> 3. it's also a good idea to run the memory check in automated test to >> locate potential issue. > This is pretty easy to do leveraging some of the code I did for POSIX > support. But: > - Due to additional time and space required it should be done only when > mm-debug is enabled. > - The additional data has to be stored before rather than after the > range since we store all the info before. > - Integrating with automated tests isn't that easy since some memory is > intentionally never freed i.a. disk cache or otherwise in use (i.a. > terminal). We need exceptions for those. > I have half-working patch, just needs few fixes. > > Patch attached. It still has a bug since printing the report to terminal may change allocations and so iterator may become invalid. That's another reason why terminal should be excluded altogether from memory tracking.
-- Regards Vladimir 'φ-coder/phcoder' Serbinenko
=== modified file 'config.h.in'
--- config.h.in 2012-02-04 20:47:29 +0000
+++ config.h.in 2012-05-01 09:53:02 +0000
@@ -8,7 +8,11 @@
#if defined (GRUB_UTIL) || !defined (GRUB_MACHINE)
#include <config-util.h>
#define NESTED_FUNC_ATTR
+#define MM_DEBUG 0
#else
+
+/* Define to 1 if you enable memory manager debugging. */
+#define MM_DEBUG @MM_DEBUG@
/* Define if C symbols get an underscore after compilation. */
#define HAVE_ASM_USCORE @HAVE_ASM_USCORE@
/* Define it to \"addr32\" or \"addr32;\" to make GAS happy. */
=== modified file 'configure.ac'
--- configure.ac 2012-04-29 16:15:24 +0000
+++ configure.ac 2012-05-01 09:53:58 +0000
@@ -759,9 +759,14 @@
# Memory manager debugging.
AC_ARG_ENABLE([mm-debug],
AS_HELP_STRING([--enable-mm-debug],
- [include memory manager debugging]),
- [AC_DEFINE([MM_DEBUG], [1],
- [Define to 1 if you enable memory manager debugging.])])
+ [include memory manager debugging]))
+if test x$enable_mm_debug = xyes; then
+ MM_DEBUG=1
+else
+ MM_DEBUG=0
+fi
+
+AC_SUBST([MM_DEBUG])
AC_ARG_ENABLE([cache-stats],
AS_HELP_STRING([--enable-cache-stats],
@@ -786,6 +791,10 @@
[AS_HELP_STRING([--enable-grub-emu-pci],
[build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])])
+if test "$platform" = emu && test "$MM_DEBUG" = 1; then
+ AC_MSG_ERROR([grub-emu doesn't support mm-debug])
+fi
+
if test "$platform" = emu; then
missing_ncurses=
[# Check for curses libraries.]
@@ -1132,6 +1141,7 @@
AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1])
AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes])
AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1])
+AM_CONDITIONAL([COND_ENABLE_MM_DEBUG], [test x$MM_DEBUG = x1])
AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1])
AM_CONDITIONAL([COND_CYGWIN], [test x$host_os = xcygwin])
=== modified file 'grub-core/Makefile.core.def'
--- grub-core/Makefile.core.def 2012-04-01 19:35:18 +0000
+++ grub-core/Makefile.core.def 2012-04-30 18:22:33 +0000
@@ -1816,6 +1816,13 @@
};
module = {
+ name = printmem;
+ common = commands/printmem.c;
+ condition = COND_ENABLE_MM_DEBUG;
+ enable = noemu;
+};
+
+module = {
name = adler32;
common = lib/adler32.c;
};
=== added file 'grub-core/commands/printmem.c'
--- grub-core/commands/printmem.c 1970-01-01 00:00:00 +0000
+++ grub-core/commands/printmem.c 2012-05-01 10:20:29 +0000
@@ -0,0 +1,75 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/mm_private.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_err_t
+grub_cmd_print_mem (grub_command_t ctxt __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+{
+ grub_mm_header_t cur;
+ for (cur = grub_mm_allocated; cur; cur = cur->next)
+ {
+ struct grub_mm_alloc_info *info = (struct grub_mm_alloc_info *) (cur + 1);
+ if (grub_strcmp (info->file, "kern/dl.c") == 0
+ || grub_strcmp (info->file, "kern/env.c") == 0
+ || grub_strcmp (info->file, "kern/disk.c") == 0
+ || grub_strcmp (info->file, "kern/command.c") == 0
+ || grub_strcmp (info->file, "kern/parser.c") == 0
+ || grub_strcmp (info->file, "normal/dyncmd.c") == 0
+ || grub_strcmp (info->file, "normal/autofs.c") == 0
+ || grub_strcmp (info->file, "normal/crypto.c") == 0
+ || grub_strcmp (info->file, "normal/term.c") == 0
+ || grub_strcmp (info->file, "normal/color.c") == 0
+ || grub_strcmp (info->file, "script/script.c") == 0
+ || grub_strcmp (info->file, "script/argv.c") == 0
+ || grub_strcmp (info->file, "commands/extcmd.c") == 0)
+ continue;
+ /* TRANSLATORS: This line lists currently allocated memory.
+ First two fiels are filename and line number.
+ It's followed by the pointer and the size. */
+ grub_printf_ (N_("%s:%d %p %lu B\n"), info->file, info->lineno, cur + 1,
+ (unsigned long)
+ ((cur->size << GRUB_MM_ALIGN_LOG2) - sizeof (*cur)
+ - sizeof (*info)));
+ }
+ return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(printmem)
+{
+ cmd = grub_register_command ("printmem", grub_cmd_print_mem, 0,
+ N_("Print currently used memory."));
+}
+
+GRUB_MOD_FINI(printmem)
+{
+ grub_unregister_command (cmd);
+}
=== modified file 'grub-core/kern/misc.c'
--- grub-core/kern/misc.c 2012-02-29 18:35:19 +0000
+++ grub-core/kern/misc.c 2012-05-01 10:08:34 +0000
@@ -436,22 +436,37 @@
return num;
}
+#if MM_DEBUG
+char *
+grub_debug_strdup (const char *file, int line, const char *s)
+#else
char *
grub_strdup (const char *s)
+#endif
{
grub_size_t len;
char *p;
len = grub_strlen (s) + 1;
- p = (char *) grub_malloc (len);
+#if MM_DEBUG
+ p = (char *) grub_debug_malloc (file, line, len);
+#else
+ p = (char *) grub_malloc (len);
+#endif
if (! p)
return 0;
return grub_memcpy (p, s, len);
}
+
+#if MM_DEBUG
+char *
+grub_debug_strndup (const char *file, int line, const char *s, grub_size_t n)
+#else
char *
grub_strndup (const char *s, grub_size_t n)
+#endif
{
grub_size_t len;
char *p;
@@ -459,7 +474,11 @@
len = grub_strlen (s);
if (len > n)
len = n;
+#if MM_DEBUG
+ p = (char *) grub_debug_malloc (file, line, len + 1);
+#else
p = (char *) grub_malloc (len + 1);
+#endif
if (! p)
return 0;
@@ -1051,8 +1070,13 @@
return ret;
}
+#if MM_DEBUG
+char *
+grub_debug_xvasprintf (const char *file, int line, const char *fmt, va_list ap)
+#else
char *
grub_xvasprintf (const char *fmt, va_list ap)
+#endif
{
grub_size_t s, as = PREALLOC_SIZE;
char *ret;
@@ -1060,7 +1084,11 @@
while (1)
{
va_list ap2;
+#if MM_DEBUG
+ ret = grub_debug_malloc (file, line, as + 1);
+#else
ret = grub_malloc (as + 1);
+#endif
if (!ret)
return NULL;
@@ -1078,14 +1106,23 @@
}
}
+#if MM_DEBUG
+char *
+grub_debug_xasprintf (const char *file, int line, const char *fmt, ...)
+#else
char *
grub_xasprintf (const char *fmt, ...)
+#endif
{
va_list ap;
char *ret;
va_start (ap, fmt);
+#if MM_DEBUG
+ ret = grub_debug_xvasprintf (file, line, fmt, ap);
+#else
ret = grub_xvasprintf (fmt, ap);
+#endif
va_end (ap);
return ret;
=== modified file 'grub-core/kern/mm.c'
--- grub-core/kern/mm.c 2012-02-03 13:20:31 +0000
+++ grub-core/kern/mm.c 2012-05-01 09:50:18 +0000
@@ -68,7 +68,7 @@
#include <grub/i18n.h>
#include <grub/mm_private.h>
-#ifdef MM_DEBUG
+#if MM_DEBUG
# undef grub_malloc
# undef grub_zalloc
# undef grub_realloc
@@ -84,10 +84,13 @@
to the header and a pointer to its region, respectively. PTR must
be allocated. */
static void
-get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r)
+get_header_from_pointer (void *ptr_in, grub_mm_header_t *p, grub_mm_region_t *r)
{
- if ((grub_addr_t) ptr & (GRUB_MM_ALIGN - 1))
- grub_fatal ("unaligned pointer %p", ptr);
+ void *ptr;
+ if ((grub_addr_t) ptr_in & (GRUB_MM_ALIGN - 1))
+ grub_fatal ("unaligned pointer %p", ptr_in);
+
+ ptr = (grub_mm_header_t) ptr_in - (GRUB_MM_CELLS_METADATA - 1);
for (*r = grub_mm_base; *r; *r = (*r)->next)
if ((grub_addr_t) ptr > (grub_addr_t) ((*r) + 1)
@@ -95,11 +98,11 @@
break;
if (! *r)
- grub_fatal ("out of range pointer %p", ptr);
+ grub_fatal ("out of range pointer %p", ptr_in);
*p = (grub_mm_header_t) ptr - 1;
if ((*p)->magic != GRUB_MM_ALLOC_MAGIC)
- grub_fatal ("alloc magic is broken at %p", *p);
+ grub_fatal ("alloc magic is broken at %p: 0x%x", *p, (*p)->magic);
}
/* Initialize a region starting from ADDR and whose size is SIZE,
@@ -150,6 +153,9 @@
{
grub_mm_header_t p, q;
+ COMPILE_TIME_ASSERT (sizeof (struct grub_mm_header) == GRUB_MM_ALIGN);
+ COMPILE_TIME_ASSERT (sizeof (struct grub_mm_region) == GRUB_MM_ALIGN);
+
/* When everything is allocated side effect is that *first will have alloc
magic marked, meaning that there is no room in this region. */
if ((*first)->magic == GRUB_MM_ALLOC_MAGIC)
@@ -160,7 +166,8 @@
{
grub_off_t extra;
- extra = ((grub_addr_t) (p + 1) >> GRUB_MM_ALIGN_LOG2) % align;
+ extra = ((grub_addr_t) (p + GRUB_MM_CELLS_METADATA)
+ >> GRUB_MM_ALIGN_LOG2) & (align - 1);
if (extra)
extra = align - extra;
@@ -266,7 +273,7 @@
pieces before this will be un-used. */
*first = q;
- return p + 1;
+ return p + GRUB_MM_CELLS_METADATA;
}
/* Search was completed without result. */
@@ -282,7 +289,8 @@
grub_memalign (grub_size_t align, grub_size_t size)
{
grub_mm_region_t r;
- grub_size_t n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
+ grub_size_t n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2)
+ + GRUB_MM_CELLS_METADATA;
int count = 0;
if (!grub_mm_base)
@@ -435,7 +443,8 @@
}
/* FIXME: Not optimal. */
- n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
+ n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2)
+ + GRUB_MM_CELLS_METADATA;
get_header_from_pointer (ptr, &p, &r);
if (p->size >= n)
@@ -450,7 +459,7 @@
return q;
}
-#ifdef MM_DEBUG
+#if MM_DEBUG
int grub_mm_debug = 0;
void
@@ -510,6 +519,50 @@
grub_printf ("\n");
}
+grub_mm_header_t grub_mm_allocated;
+
+static void
+save_ref (void *ptr, int line, const char *file)
+{
+ grub_mm_header_t head;
+ struct grub_mm_alloc_info *info;
+
+ COMPILE_TIME_ASSERT ((sizeof (struct grub_mm_alloc_info)
+ & (GRUB_MM_ALIGN - 1)) == 0);
+
+ if (!ptr)
+ return;
+
+ head = ptr;
+ head -= GRUB_MM_CELLS_METADATA;
+ info = (struct grub_mm_alloc_info *) (head + 1);
+ head->next = grub_mm_allocated;
+ if (head->next)
+ head->next->prev = head;
+ head->prev = 0;
+ info->lineno = line;
+ grub_strncpy (info->file, file, sizeof (info->file));
+ grub_mm_allocated = head;
+}
+
+static void
+delete_ref (void *ptr)
+{
+ grub_mm_header_t head;
+
+ if (!ptr)
+ return;
+
+ head = ptr;
+ head -= GRUB_MM_CELLS_METADATA;
+ if (head->next)
+ head->next->prev = head->prev;
+ if (head->prev)
+ head->prev->next = head->next;
+ else if (grub_mm_allocated == head)
+ grub_mm_allocated = head->next;
+}
+
void *
grub_debug_malloc (const char *file, int line, grub_size_t size)
{
@@ -518,6 +571,7 @@
if (grub_mm_debug)
grub_printf ("%s:%d: malloc (0x%" PRIxGRUB_SIZE ") = ", file, line, size);
ptr = grub_malloc (size);
+ save_ref (ptr, line, file);
if (grub_mm_debug)
grub_printf ("%p\n", ptr);
return ptr;
@@ -531,6 +585,7 @@
if (grub_mm_debug)
grub_printf ("%s:%d: zalloc (0x%" PRIxGRUB_SIZE ") = ", file, line, size);
ptr = grub_zalloc (size);
+ save_ref (ptr, line, file);
if (grub_mm_debug)
grub_printf ("%p\n", ptr);
return ptr;
@@ -539,6 +594,7 @@
void
grub_debug_free (const char *file, int line, void *ptr)
{
+ delete_ref (ptr);
if (grub_mm_debug)
grub_printf ("%s:%d: free (%p)\n", file, line, ptr);
grub_free (ptr);
@@ -547,9 +603,11 @@
void *
grub_debug_realloc (const char *file, int line, void *ptr, grub_size_t size)
{
+ delete_ref (ptr);
if (grub_mm_debug)
grub_printf ("%s:%d: realloc (%p, 0x%" PRIxGRUB_SIZE ") = ", file, line, ptr, size);
ptr = grub_realloc (ptr, size);
+ save_ref (ptr, line, file);
if (grub_mm_debug)
grub_printf ("%p\n", ptr);
return ptr;
=== modified file 'grub-core/lib/relocator.c'
--- grub-core/lib/relocator.c 2012-04-13 14:55:20 +0000
+++ grub-core/lib/relocator.c 2012-05-01 09:34:38 +0000
@@ -358,7 +358,9 @@
r2->first = r1->first;
hl->next = r2->first;
*rp = (*rp)->next;
- grub_free (g + 1);
+ g->next = 0;
+ g->prev = 0;
+ grub_free (g + GRUB_MM_CELLS_METADATA);
}
break;
}
@@ -368,10 +370,11 @@
GRUB_MM_ALIGN);
h->size
= ((subchu->start + subchu->size + GRUB_MM_ALIGN - 1) / GRUB_MM_ALIGN)
- - (subchu->start / GRUB_MM_ALIGN) - 1;
- h->next = h;
+ - (subchu->start / GRUB_MM_ALIGN);
+ h->next = 0;
+ h->prev = 0;
h->magic = GRUB_MM_ALLOC_MAGIC;
- grub_free (h + 1);
+ grub_free (h + GRUB_MM_CELLS_METADATA);
break;
}
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
@@ -428,6 +431,9 @@
unsigned j, N = 0;
grub_addr_t target = 0;
+ COMPILE_TIME_ASSERT (sizeof (struct grub_mm_header) == GRUB_MM_ALIGN);
+ COMPILE_TIME_ASSERT (sizeof (struct grub_mm_region) == GRUB_MM_ALIGN);
+
grub_dprintf ("relocator",
"trying to allocate in 0x%lx-0x%lx aligned 0x%lx size 0x%lx\n",
(unsigned long) start, (unsigned long) end,
=== modified file 'grub-core/normal/main.c'
--- grub-core/normal/main.c 2012-03-11 13:43:18 +0000
+++ grub-core/normal/main.c 2012-05-01 10:16:23 +0000
@@ -41,8 +41,13 @@
int grub_normal_exit_level = 0;
/* Read a line from the file FILE. */
+#if MM_DEBUG
+char *
+grub_file_debug_getline (const char *cfile, int line, grub_file_t file)
+#else
char *
grub_file_getline (grub_file_t file)
+#endif
{
char c;
grub_size_t pos = 0;
@@ -51,7 +56,11 @@
grub_size_t max_len = 64;
/* Initially locate some space. */
- cmdline = grub_malloc (max_len);
+#if MM_DEBUG
+ cmdline = grub_debug_malloc (cfile, line, max_len);
+#else
+ cmdline = grub_debug_malloc (max_len);
+#endif
if (! cmdline)
return 0;
@@ -69,7 +78,11 @@
{
char *old_cmdline = cmdline;
max_len = max_len * 2;
+#if MM_DEBUG
+ cmdline = grub_debug_realloc (cfile, line, cmdline, max_len);
+#else
cmdline = grub_realloc (cmdline, max_len);
+#endif
if (! cmdline)
{
grub_free (old_cmdline);
=== modified file 'include/grub/misc.h'
--- include/grub/misc.h 2012-03-05 00:17:55 +0000
+++ include/grub/misc.h 2012-05-01 10:07:51 +0000
@@ -314,8 +314,16 @@
}
}
+#if MM_DEBUG
+char *EXPORT_FUNC(grub_debug_strdup) (const char *file, int line, const char *s) __attribute__ ((warn_unused_result));
+char *EXPORT_FUNC(grub_debug_strndup) (const char *file, int line, const char *s, grub_size_t n) __attribute__ ((warn_unused_result));
+
+#define grub_strdup(s) grub_debug_strdup (GRUB_FILE, __LINE__, s)
+#define grub_strndup(s, n) grub_debug_strndup (GRUB_FILE, __LINE__, s, n)
+#else
char *EXPORT_FUNC(grub_strdup) (const char *s) __attribute__ ((warn_unused_result));
char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) __attribute__ ((warn_unused_result));
+#endif
void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) __attribute__ ((warn_unused_result));
int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
@@ -363,9 +371,17 @@
__attribute__ ((format (printf, 3, 4)));
int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt,
va_list args);
+#if MM_DEBUG
+char *EXPORT_FUNC(grub_debug_xasprintf) (const char *file, int line, const char *fmt, ...)
+ __attribute__ ((format (printf, 3, 4))) __attribute__ ((warn_unused_result));
+char *EXPORT_FUNC(grub_debug_xvasprintf) (const char *file, int line, const char *fmt, va_list args) __attribute__ ((warn_unused_result));
+#define grub_xasprintf(fmt, args...) grub_debug_xasprintf (GRUB_FILE, __LINE__, fmt, ## args)
+#define grub_xvasprintf(fmt, args) grub_debug_xvasprintf (GRUB_FILE, __LINE__, fmt, args)
+#else
char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
__attribute__ ((format (printf, 1, 2))) __attribute__ ((warn_unused_result));
char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) __attribute__ ((warn_unused_result));
+#endif
void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
=== modified file 'include/grub/mm.h'
--- include/grub/mm.h 2011-11-13 11:48:39 +0000
+++ include/grub/mm.h 2012-05-01 09:53:09 +0000
@@ -39,7 +39,7 @@
#define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__);
/* For debugging. */
-#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU)
+#if MM_DEBUG
/* Set this variable to 1 when you want to trace all memory function calls. */
extern int EXPORT_VAR(grub_mm_debug);
=== modified file 'include/grub/mm_private.h'
--- include/grub/mm_private.h 2010-08-28 12:52:25 +0000
+++ include/grub/mm_private.h 2012-05-01 09:46:58 +0000
@@ -30,13 +30,7 @@
struct grub_mm_header *next;
grub_size_t size;
grub_size_t magic;
-#if GRUB_CPU_SIZEOF_VOID_P == 4
- char padding[4];
-#elif GRUB_CPU_SIZEOF_VOID_P == 8
- char padding[8];
-#else
-# error "unknown word size"
-#endif
+ struct grub_mm_header *prev;
}
*grub_mm_header_t;
@@ -48,6 +42,17 @@
#define GRUB_MM_ALIGN (1 << GRUB_MM_ALIGN_LOG2)
+#if MM_DEBUG
+struct grub_mm_alloc_info
+{
+ int lineno;
+ char file[128 - sizeof (int)];
+};
+static const grub_size_t GRUB_MM_CELLS_METADATA = ((sizeof (struct grub_mm_alloc_info) >> GRUB_MM_ALIGN_LOG2) + 1);
+#else
+#define GRUB_MM_CELLS_METADATA 1
+#endif
+
typedef struct grub_mm_region
{
struct grub_mm_header *first;
@@ -61,4 +66,8 @@
extern grub_mm_region_t EXPORT_VAR (grub_mm_base);
#endif
+#if MM_DEBUG
+extern grub_mm_header_t EXPORT_VAR(grub_mm_allocated);
+#endif
+
#endif
=== modified file 'include/grub/normal.h'
--- include/grub/normal.h 2012-03-10 22:25:34 +0000
+++ include/grub/normal.h 2012-05-01 10:15:01 +0000
@@ -51,7 +51,14 @@
void grub_menu_init_page (int nested, int edit, int *num_entries,
struct grub_term_output *term);
void grub_normal_init_page (struct grub_term_output *term);
+#if MM_DEBUG
+char *grub_file_debug_getline (const char *call_file,
+ int line, grub_file_t file);
+#define grub_file_getline(file) \
+ grub_file_debug_getline (GRUB_FILE, __LINE__, file)
+#else
char *grub_file_getline (grub_file_t file);
+#endif
void grub_cmdline_run (int nested);
/* Defined in `cmdline.c'. */
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Grub-devel mailing list [email protected] https://lists.gnu.org/mailman/listinfo/grub-devel
