diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/stdlib/.cvsignore | 2 | ||||
-rw-r--r-- | test/stdlib/Makefile | 31 | ||||
-rw-r--r-- | test/stdlib/mallocbug.c | 67 |
3 files changed, 98 insertions, 2 deletions
diff --git a/test/stdlib/.cvsignore b/test/stdlib/.cvsignore index 185db39b2..89fe8faa4 100644 --- a/test/stdlib/.cvsignore +++ b/test/stdlib/.cvsignore @@ -7,3 +7,5 @@ teststrtol_glibc teststrtol.o teststrtol.out teststrtol_glibc.out +mallocbug +mallocbug_glibc diff --git a/test/stdlib/Makefile b/test/stdlib/Makefile index e882d8f85..4cd6e5765 100644 --- a/test/stdlib/Makefile +++ b/test/stdlib/Makefile @@ -19,8 +19,9 @@ ifndef $(STRIPTOOL) endif STRIP = $(STRIPTOOL) --remove-section=.note --remove-section=.comment $@ -TARGETS=testmalloc_source testmalloc testmalloc_glibc -TARGETS+=teststrtol_source teststrtol teststrtol_glibc teststrtol_diff +TARGETS=testmalloc testmalloc_glibc +TARGETS=mallocbug mallocbug_glibc +TARGETS+=teststrtol teststrtol_glibc teststrtol_diff all: $(TARGETS) @@ -57,6 +58,32 @@ testmalloc_glibc: testmalloc.c Makefile $(TOPDIR)libc.a -./$@ -@ echo " " +mallocbug: mallocbug.c Makefile $(TOPDIR)libc.a + -@ echo "-------" + -@ echo " " + -@ echo "Compiling vs uC-Libc: " + -@ echo " " + $(CC) -g $(XCFLAGS) -c $< -o $@.o + $(CC) -g $(XLDFLAGS) $@.o -o $@ $(EXTRA_LIBS) + $(STRIP) + -ldd $@ + ls $(LSFLAGS) $@ + -./$@ + -@ echo " " + +mallocbug_glibc: mallocbug.c Makefile $(TOPDIR)libc.a + -@ echo "-------" + -@ echo " " + -@ echo "Compiling vs GNU libc: " + -@ echo " " + $(CC) $(YCFLAGS) -c $< -o $@.o + $(CC) $(YLDFLAGS) --static $@.o -o $@ + $(STRIP) + -ldd $@ + ls $(LSFLAGS) $@ + -./$@ + -@ echo " " + teststrtol_source: -@ echo "-------" -@ echo "teststrtol.c source: " diff --git a/test/stdlib/mallocbug.c b/test/stdlib/mallocbug.c new file mode 100644 index 000000000..84a638795 --- /dev/null +++ b/test/stdlib/mallocbug.c @@ -0,0 +1,67 @@ +/* Reproduce a GNU malloc bug. */ +#include <malloc.h> +#include <stdio.h> +#include <string.h> + +#define size_t unsigned int + +int +main (int argc, char *argv[]) +{ + char *dummy0; + char *dummy1; + char *fill_info_table1; + char *over_top; + size_t over_top_size = 0x3000; + char *over_top_dup; + size_t over_top_dup_size = 0x7000; + char *x; + size_t i; + + /* Here's what memory is supposed to look like (hex): + size contents + 3000 original_info_table, later fill_info_table1 + 3fa000 dummy0 + 3fa000 dummy1 + 6000 info_table_2 + 3000 over_top + + */ + /* mem: original_info_table */ + dummy0 = malloc (0x3fa000); + /* mem: original_info_table, dummy0 */ + dummy1 = malloc (0x3fa000); + /* mem: free, dummy0, dummy1, info_table_2 */ + fill_info_table1 = malloc (0x3000); + /* mem: fill_info_table1, dummy0, dummy1, info_table_2 */ + + x = malloc (0x1000); + free (x); + /* mem: fill_info_table1, dummy0, dummy1, info_table_2, freexx */ + + /* This is what loses; info_table_2 and freexx get combined unbeknownst + to mmalloc, and mmalloc puts over_top in a section of memory which + is on the free list as part of another block (where info_table_2 had + been). */ + over_top = malloc (over_top_size); + over_top_dup = malloc (over_top_dup_size); + memset (over_top, 0, over_top_size); + memset (over_top_dup, 1, over_top_dup_size); + + for (i = 0; i < over_top_size; ++i) + if (over_top[i] != 0) + { + printf ("FAIL: malloc expands info table\n"); + return 0; + } + + for (i = 0; i < over_top_dup_size; ++i) + if (over_top_dup[i] != 1) + { + printf ("FAIL: malloc expands info table\n"); + return 0; + } + + printf ("PASS: malloc expands info table\n"); + return 0; +} |