Browse Source

test: Support testing malloc() failures

It is helpful to test that out-of-memory checks work correctly in code
that calls malloc().

Add a simple way to force failure after a given number of malloc() calls.

Fix a header guard to avoid a build error on sandbox_vpl.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Sean Anderson <seanga2@gmail.com>
Simon Glass 1 year ago
parent
commit
62d638386c
4 changed files with 33 additions and 0 deletions
  1. 1 0
      arch/sandbox/include/asm/malloc.h
  2. 19 0
      common/dlmalloc.c
  3. 12 0
      include/malloc.h
  4. 1 0
      test/test-main.c

+ 1 - 0
arch/sandbox/include/asm/malloc.h

@@ -6,6 +6,7 @@
  */
 
 #ifndef __ASM_MALLOC_H
+#define __ASM_MALLOC_H
 
 void *malloc(size_t size);
 void free(void *ptr);

+ 19 - 0
common/dlmalloc.c

@@ -596,6 +596,9 @@ ulong mem_malloc_start = 0;
 ulong mem_malloc_end = 0;
 ulong mem_malloc_brk = 0;
 
+static bool malloc_testing;	/* enable test mode */
+static int malloc_max_allocs;	/* return NULL after this many calls to malloc() */
+
 void *sbrk(ptrdiff_t increment)
 {
 	ulong old = mem_malloc_brk;
@@ -1307,6 +1310,11 @@ Void_t* mALLOc(bytes) size_t bytes;
 		return malloc_simple(bytes);
 #endif
 
+  if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) {
+    if (--malloc_max_allocs < 0)
+      return NULL;
+  }
+
   /* check if mem_malloc_init() was run */
   if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) {
     /* not initialized yet */
@@ -2470,6 +2478,17 @@ int initf_malloc(void)
 	return 0;
 }
 
+void malloc_enable_testing(int max_allocs)
+{
+	malloc_testing = true;
+	malloc_max_allocs = max_allocs;
+}
+
+void malloc_disable_testing(void)
+{
+	malloc_testing = false;
+}
+
 /*
 
 History:

+ 12 - 0
include/malloc.h

@@ -883,6 +883,18 @@ extern Void_t*     sbrk();
 
 void malloc_simple_info(void);
 
+/**
+ * malloc_enable_testing() - Put malloc() into test mode
+ *
+ * This only works if UNIT_TESTING is enabled
+ *
+ * @max_allocs: return -ENOMEM after max_allocs calls to malloc()
+ */
+void malloc_enable_testing(int max_allocs);
+
+/** malloc_disable_testing() - Put malloc() into normal mode */
+void malloc_disable_testing(void);
+
 #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE)
 #define malloc malloc_simple
 #define realloc realloc_simple

+ 1 - 0
test/test-main.c

@@ -47,6 +47,7 @@ static int dm_test_pre_run(struct unit_test_state *uts)
 	uts->force_fail_alloc = false;
 	uts->skip_post_probe = false;
 	gd->dm_root = NULL;
+	malloc_disable_testing();
 	if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA))
 		memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
 	arch_reset_for_test();