diff --git a/repos/libports/run/libc.run b/repos/libports/run/libc.run
index 4af7229bd2..a0656f0c1b 100644
--- a/repos/libports/run/libc.run
+++ b/repos/libports/run/libc.run
@@ -19,9 +19,9 @@ install_config {
-
+
-
+
@@ -35,7 +35,7 @@ build_boot_image {
ld.lib.so libc.lib.so libm.lib.so posix.lib.so
}
-append qemu_args " -nographic -m 64 "
+append qemu_args " -nographic -m 512 "
run_genode_until "child .* exited with exit value 0.*\n" 10
diff --git a/repos/libports/src/test/libc/main.cc b/repos/libports/src/test/libc/main.cc
index 6139408e6f..40f583a13c 100644
--- a/repos/libports/src/test/libc/main.cc
+++ b/repos/libports/src/test/libc/main.cc
@@ -1,6 +1,8 @@
/*
* \brief LibC test program used during the libC porting process
* \author Norman Feske
+ * \author Alexander Böttcher
+ * \author Christian Helmuth
* \date 2008-10-22
*/
@@ -21,8 +23,8 @@
/* libC includes */
#include
#include
+#include
-void *addr = 0;
int main(int argc, char **argv)
{
@@ -31,10 +33,89 @@ int main(int argc, char **argv)
printf("Does printf work?\n");
printf("We can find out by printing a floating-point number: %f. How does that work?\n", 1.2345);
- printf("Malloc test\n");
- addr = malloc(1234);
- printf("Malloc returned addr = %p\n", addr);
- printf("--- exit(0) from main ---\n");
- exit(0);
+ enum { ROUNDS = 64, SIZE_LARGE = 2048 };
+
+ unsigned error_count = 0;
+
+ printf("Malloc: check small sizes\n");
+ for (size_t size = 1; size < SIZE_LARGE; size = 2*size + 3) {
+ void *addr[ROUNDS];
+ for (unsigned i = 0; i < ROUNDS; ++i) {
+ addr[i] = malloc(size);
+
+ if (!((unsigned long)addr[i] & 0xf))
+ continue;
+
+ printf("%u. malloc(%zu) returned addr = %p - ERROR\n", i, size, addr[i]);
+ ++error_count;
+ }
+ for (unsigned i = 0; i < ROUNDS; ++i) free(addr[i]);
+ }
+
+ printf("Malloc: check larger sizes\n");
+ for (size_t size = SIZE_LARGE; size < 1024*1024; size = 2*size + 15) {
+ void *addr[ROUNDS];
+ for (unsigned i = 0; i < ROUNDS; ++i) {
+ addr[i] = malloc(size);
+
+ if (!((unsigned long)addr[i] & 0xf))
+ continue;
+
+ printf("%u. malloc(%zu) returned addr = %p - ERROR\n", i, size, addr[i]);
+ ++error_count;
+ }
+ for (unsigned i = 0; i < ROUNDS; ++i) free(addr[i]);
+ }
+
+ printf("Malloc: check realloc\n");
+ {
+ void *addr = malloc(32);
+ memset(addr, 13, 32);
+
+ for (unsigned i = 0; i < ROUNDS; ++i) {
+ size_t const size = 32 + 11*i;
+ char *a = (char *)realloc(addr, size);
+ if (memcmp(addr, a, 32) || a[32] != 0) {
+ printf("realloc data error");
+ ++error_count;
+ }
+ addr = a;
+
+ if (!((unsigned long)addr & 0xf))
+ continue;
+
+ printf("%u. realloc(%zu) returned addr = %p - ERROR\n", i, size, addr);
+ ++error_count;
+ }
+ for (int i = ROUNDS - 1; i >= 0; --i) {
+ size_t const size = 32 + 11*i;
+ char *a = (char *)realloc(addr, size);
+ if (memcmp(addr, a, 32) || a[32] != 0) {
+ printf("realloc data error");
+ ++error_count;
+ }
+ addr = a;
+
+ if (!((unsigned long)addr & 0xf))
+ continue;
+
+ printf("%u. realloc(%zu) returned addr = %p - ERROR\n", i, size, addr);
+ ++error_count;
+ }
+ }
+
+ printf("Malloc: check really large allocation\n");
+ for (unsigned i = 0; i < 4; ++i) {
+ size_t const size = 250*1024*1024;
+ void *addr = malloc(size);
+ free(addr);
+
+ if ((unsigned long)addr & 0xf) {
+ printf("large malloc(%zu) returned addr = %p - ERROR\n", size, addr);
+ ++error_count;
+ }
+ }
+
+ exit(error_count);
}