aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/dlmalloc_proxy.c85
-rw-r--r--tests/test_core.py34
2 files changed, 119 insertions, 0 deletions
diff --git a/tests/dlmalloc_proxy.c b/tests/dlmalloc_proxy.c
new file mode 100644
index 00000000..33435dd8
--- /dev/null
+++ b/tests/dlmalloc_proxy.c
@@ -0,0 +1,85 @@
+// Emscripten tests
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <dlfcn.h>
+
+typedef void *(*mallocer)(int n);
+typedef void (*freeer)(void *p);
+
+void *lib_handle;
+int handles = 0;
+mallocer mallocproxy = NULL;
+freeer freeproxy = NULL;
+
+void get_lib() {
+ printf("get lib\n");
+ lib_handle = dlopen("liblib.so", RTLD_NOW);
+ assert(lib_handle != NULL);
+ handles++;
+
+ mallocproxy = (mallocer)dlsym(lib_handle, "mallocproxy");
+ assert(mallocproxy!= NULL);
+ freeproxy = (freeer)dlsym(lib_handle, "freeproxy");
+ assert(freeproxy!= NULL);
+}
+
+void unget_lib() {
+ printf("unget lib\n");
+ assert(lib_handle);
+ dlclose(lib_handle);
+ handles--;
+ if (handles == 0) lib_handle = NULL;
+}
+
+int main() {
+ int n = 0, total = 0, l = 0;
+ void *allocs[50];
+ allocs[10] = malloc(10); // pull in real malloc
+ for (int i = 0; i < 500; i++) {
+ printf("%d: total ever %d MB, current MB %d, total libs %d\n", i, total, n, l);
+ if (i % 5 == 0) {
+ if (handles < 10) {
+ get_lib();
+ l++;
+ }
+ }
+ if (i % 7 == 0) {
+ if (handles > 0) unget_lib();
+ }
+ if (i % 3 == 0) {
+ if (handles > 0) {
+ if (n < 10) {
+ if (i % 2 == 0) {
+ printf("alloc\n");
+ allocs[n++] = mallocproxy(1024*1024);
+ } else {
+ printf("real alloc\n");
+ allocs[n++] = malloc(1024*1024);
+ }
+ total++;
+ } else {
+ printf("real free\n");
+ free(allocs[--n]); // real free
+ }
+ }
+ }
+ if (i % 4 == 0) {
+ if (handles > 0 && n > 0) {
+ printf("free\n");
+ if (i % 2 == 0) {
+ printf("free\n");
+ freeproxy(allocs[--n]);
+ } else {
+ printf("real free\n");
+ free(allocs[--n]);
+ }
+ }
+ }
+ }
+ while (n > 0) free(allocs[--n]); // real free
+ while (handles > 0) unget_lib();
+ printf("*%d,%d*\n", total, l);
+}
+
diff --git a/tests/test_core.py b/tests/test_core.py
index f98d3624..d7e60345 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -6198,6 +6198,40 @@ int 1 9000
ok
''', force_c=True, post_build=self.dlfcn_post_build)
+ def test_dlfcn_mallocs(self):
+ if not self.can_dlfcn(): return
+
+ Settings.TOTAL_MEMORY = 64*1024*1024 # will be exhausted without functional malloc/free
+
+ self.prep_dlfcn_lib()
+ lib_src = r'''
+ #include <assert.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+
+ void *mallocproxy(int n) { return malloc(n); }
+ void freeproxy(void *p) { free(p); }
+ '''
+ Settings.EXPORTED_FUNCTIONS = ['_mallocproxy', '_freeproxy']
+ dirname = self.get_dir()
+ filename = os.path.join(dirname, 'liblib.c')
+ self.build(lib_src, dirname, filename)
+ shutil.move(filename + '.o.js', os.path.join(dirname, 'liblib.so'))
+
+ self.prep_dlfcn_main()
+ src = open(path_from_root('tests', 'dlmalloc_proxy.c')).read()
+ Settings.EXPORTED_FUNCTIONS = ['_main', '_malloc', '_free']
+ self.do_run(src, '''go
+main.
+main 201
+void 0
+void 1
+int 0 54
+int 1 9000
+ok
+''', force_c=True, post_build=self.dlfcn_post_build)
+
def test_rand(self):
return self.skip('rand() is now random') # FIXME