Commit 31435c717b48b87bc0112ab2e2af3b513794f598

Thomas de Grivel 2024-12-27T15:48:51

wip alloc

diff --git a/Makefile b/Makefile
index 6d4a63a..b9a7e97 100644
--- a/Makefile
+++ b/Makefile
@@ -325,6 +325,12 @@ gdb_test:
 	${MAKE} -C libkc3 debug
 	${MAKE} -C test gdb_test
 
+gdb_test_asan:
+	${MAKE} -C libtommath asan
+	${MAKE} -C ucd2c
+	${MAKE} -C libkc3 asan
+	${MAKE} -C test gdb_test_asan
+
 gdb_test_ekc3:
 	${MAKE} -C libtommath debug
 	${MAKE} -C ucd2c
diff --git a/libkc3/alloc.c b/libkc3/alloc.c
index 179b166..fc6bb87 100644
--- a/libkc3/alloc.c
+++ b/libkc3/alloc.c
@@ -11,6 +11,7 @@
  * THIS SOFTWARE.
  */
 #include <errno.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
@@ -48,6 +49,15 @@ void * alloc (uw size)
   }
   skiplist_insert__alloc(g_alloc_skiplist_mapped_size, a);
   skiplist_insert__alloc(g_alloc_skiplist_size_mapped, a);
+  if (false) {
+    err_write_1("alloc: size = ");
+    err_inspect_uw_decimal(&size);
+    err_write_1(", a = ");
+    err_inspect_ptr((const u_ptr_w *) &a);
+    err_write_1(" => ");
+    err_inspect_ptr((const u_ptr_w *) &a->mapped);
+    err_write_1("\n");
+  }
   return a->mapped;
 }
 
@@ -60,6 +70,55 @@ void alloc_clean (void)
   }
 }
 
+void alloc_free (void *allocated)
+{
+  s_alloc *al;
+  const char *err = NULL;
+  s_skiplist_node__alloc *node;
+  s_skiplist_node__alloc *pred;
+  s_alloc                 pred_alloc = {0};
+  if (false) {
+    err_write_1("alloc_free: allocated = ");
+    err_inspect_ptr((const u_ptr_w *) &allocated);
+    err_write_1("\n");
+  }
+  if (! allocated)
+    return;
+  pred_alloc.mapped = allocated;
+  if (! (pred = skiplist_pred__alloc(g_alloc_skiplist_mapped_size,
+                                     &pred_alloc))) {
+    err = "skiplist_pred__alloc";
+    goto ko;
+  }
+  if (! (node = SKIPLIST_NODE_NEXT__alloc(pred, 0))) {
+    err = "SKIPLIST_NODE_NEXT__alloc 1";
+    goto ko;
+  }
+  if (! (node = SKIPLIST_NODE_NEXT__alloc(node, 0))) {
+    err = "SKIPLIST_NODE_NEXT__alloc 2";
+    goto ko;
+  }
+  if (! node->alloc) {
+    err = "! node->alloc";
+    goto ko;
+  }
+  al = node->alloc;
+  if (al->mapped != allocated) {
+    err = "al->mapped != allocated";
+    goto ko;
+  }
+  skiplist_remove__alloc(g_alloc_skiplist_mapped_size, al);
+  skiplist_remove__alloc(g_alloc_skiplist_size_mapped, al);
+  alloc_unmap(allocated, al->size);
+  alloc_unmap(al, sizeof(s_alloc));
+  return;
+ ko:
+  err_write_1("free: invalid argument: ");
+  err_write_1(err);
+  err_write_1("\n");
+  assert(! "free: invalid argument");
+}
+
 s8 alloc_init (void)
 {
   if (g_alloc_init) {
@@ -81,32 +140,6 @@ s8 alloc_init (void)
   g_alloc_init = 1;
   return 0;
 }
-
-void alloc_free (void *allocated)
-{
-  s_alloc *al;
-  s_skiplist_node__alloc *node;
-  s_skiplist_node__alloc *pred;
-  s_alloc                 pred_alloc = {0};
-  if (! allocated)
-    return;
-  pred_alloc.mapped = allocated;
-  if (! (pred = skiplist_pred__alloc(g_alloc_skiplist_mapped_size,
-                                     &pred_alloc)))
-    goto ko;
-  if (! (node = SKIPLIST_NODE_NEXT__alloc(pred, 0)))
-    goto ko;
-  al = node->alloc;
-  if (al->mapped != allocated)
-    goto ko;
-  alloc_unmap(allocated, al->size);
-  skiplist_remove__alloc(g_alloc_skiplist_mapped_size, al);
-  skiplist_remove__alloc(g_alloc_skiplist_size_mapped, al);
-  alloc_unmap(al, sizeof(s_alloc));
- ko:
-  err_puts("free: invalid argument");
-  assert(! "free: invalid argument");
-}
   
 void * alloc_map (uw size)
 {
@@ -122,17 +155,20 @@ void * alloc_map (uw size)
     return NULL;
   }
   bzero(mapped, size);
+  if (false)
+    printf("alloc_map: size = %lu => %p", size, mapped);
   return mapped;
 }
 
 void alloc_unmap (void *mapped, uw size)
 {
   sw e;
+  assert(size);
+  if (false)
+    printf("alloc_unmap: size = %lu, mapped = %p", size, mapped);
   if (munmap(mapped, size) < 0) {
     e = errno;
-    err_write_1("alloc_unmap: munmap: ");
-    err_write_1(strerror(e));
-    err_write_1("\n");
-    assert(! "alloc_unmap: munmap");
+    fprintf(stderr, "alloc_unmap: size = %lu, mapped = %p", size, mapped);
+    fprintf(stderr, "alloc_unmap: munmap: %s", strerror(e));
   }
 }
diff --git a/libkc3/buf_parse.c b/libkc3/buf_parse.c
index de6cf58..a79adb5 100644
--- a/libkc3/buf_parse.c
+++ b/libkc3/buf_parse.c
@@ -886,7 +886,7 @@ sw buf_parse_call_op (s_buf *buf, s_call *dest)
   sw r;
   sw result = 0;
   s_buf_save save;
-  s_call tmp;
+  s_call tmp = {0};
   assert(buf);
   assert(dest);
   buf_save_init(buf, &save);
diff --git a/libkc3/callable.c b/libkc3/callable.c
index 50ebb1f..faa46c8 100644
--- a/libkc3/callable.c
+++ b/libkc3/callable.c
@@ -103,6 +103,8 @@ s_callable * callable_new_ref (s_callable *callable)
 
 void p_callable_clean (p_callable *callable)
 {
+  assert(callable);
+  assert(*callable);
   callable_delete(*callable);
 }
 
diff --git a/libkc3/configure b/libkc3/configure
index cf89913..3d96856 100755
--- a/libkc3/configure
+++ b/libkc3/configure
@@ -71,9 +71,9 @@ fi
 
 # Address Sanitizer config
 CPPFLAGS_ASAN="$CPPFLAGS"
-CFLAGS_ASAN="$CFLAGS -DDEBUG -Oz -g"
+CFLAGS_ASAN="$CFLAGS -DDEBUG -O2 -g"
 CFLAGS_ASAN="$CFLAGS_ASAN -fsanitize=address -fno-omit-frame-pointer"
-CXXFLAGS_ASAN="$CXXFLAGS -DDEBUG -Oz -g"
+CXXFLAGS_ASAN="$CXXFLAGS -DDEBUG -O2 -g"
 CXXFLAGS_ASAN="$CXXFLAGS_ASAN -fsanitize=address -fno-omit-frame-pointer"
 LDFLAGS_ASAN="$LDFLAGS"
 LIBS_ASAN="$LIBS"
@@ -98,7 +98,7 @@ if [ "x$ENV_CFLAGS" = "x" ]; then
     CFLAGS="$CFLAGS $DEFAULT_CFLAGS"
 fi
 CFLAGS="$CFLAGS -DNDEBUG"
-DEFAULT_CXXFLAGS="-Oz -fPIC"
+DEFAULT_CXXFLAGS="-O2 -fPIC"
 if [ "x$ENV_CXXFLAGS" = "x" ]; then
     CXXFLAGS="$CXXFLAGS $DEFAULT_CXXFLAGS"
 fi
diff --git a/libkc3/env.c b/libkc3/env.c
index 5cd2476..8dca2e6 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -1754,7 +1754,7 @@ bool env_eval_quote_struct (s_env *env, s_struct *s, s_tag *dest)
     return true;
   }
   t->type = s->type;
-  t->tag = alloc(t->type->map.count * sizeof(s_tag));
+  t->tag = alloc_map(t->type->map.count * sizeof(s_tag));
   if (! t->tag)
     return false;
   i = 0;
@@ -1850,14 +1850,13 @@ bool env_eval_quote_time (s_env *env, s_time *time, s_tag *dest)
     if (! env_eval_quote_tag(env, time->tag, tmp.tag)) {
       err_puts("env_eval_quote_time: env_eval_quote_tag: tv_sec");
       assert(! "env_eval_quote_time: env_eval_quote_tag: tv_sec");
-      alloc_unmap(tmp.tag, sizeof(s_tag) * 2);
+      time_clean(&tmp);
       return false;
     }
     if (! env_eval_quote_tag(env, time->tag + 1, tmp.tag + 1)) {
       err_puts("env_eval_quote_time: env_eval_quote_tag: tv_nsec");
       assert(! "env_eval_quote_time: env_eval_quote_tag: tv_nsec");
-      tag_clean(tmp.tag);
-      alloc_unmap(tmp.tag, sizeof(s_tag) * 2);
+      time_clean(&tmp);
       return false;
     }
   }
@@ -2675,12 +2674,11 @@ s_ident * env_ident_resolve_module (s_env *env,
 s_env * env_init (s_env *env, int *argc, char ***argv)
 {
   s_str path;
-  sym_init_g_sym();
   alloc_init();
   if (! env)
     env = g_kc3_env;
   if (! env)
-    env = g_kc3_env = alloc(sizeof(s_env));
+    env = g_kc3_env = alloc_map(sizeof(s_env));
   if (! env)
     return NULL;
   env->trace = false;
@@ -2700,6 +2698,7 @@ s_env * env_init (s_env *env, int *argc, char ***argv)
   if (! (env->err = buf_new_alloc(BUF_SIZE)))
     return NULL;
   buf_file_open_w(env->err, stderr);
+  sym_init_g_sym();
   env->facts = facts_new();
   env->path = list_new_str_1
     (NULL, "./", list_new_str_1
@@ -2711,7 +2710,7 @@ s_env * env_init (s_env *env, int *argc, char ***argv)
           (NULL, "../../../../../", list_new_str_1
            (NULL, "../../../../../../", NULL))))))));
   str_init_1(&path, NULL, "lib/kc3/0.1/");
-  if (! (env->module_path = alloc(sizeof(s_str))))
+  if (! (env->module_path = alloc_map(sizeof(s_str))))
     return NULL;
   if (! file_search(&path, &g_sym_x, env->module_path)) {
     err_puts("env_init: lib/kc3/0.1 not found in module path");
@@ -2739,7 +2738,7 @@ s_env * env_init_args (s_env *env, int *argc, char ***argv)
     env->argc = (*argc)--;
     env->argv = (*argv)++;
     str_init_1(&argv0, NULL, env->argv[0]);
-    if (! (env->argv0_dir = alloc(sizeof(s_str))))
+    if (! (env->argv0_dir = alloc_map(sizeof(s_str))))
       return NULL;
     file_dirname(&argv0, env->argv0_dir);
     while (*argc > 0 && *argc != argc_prev) {
diff --git a/libkc3/fact_action.c b/libkc3/fact_action.c
index b145a23..7d347d3 100644
--- a/libkc3/fact_action.c
+++ b/libkc3/fact_action.c
@@ -10,7 +10,7 @@
  * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
  * THIS SOFTWARE.
  */
-#include <stdlib.h>
+#include "alloc.h"
 #include "fact_action.h"
 
 void fact_action_delete_all (s_fact_action *action)
@@ -18,7 +18,7 @@ void fact_action_delete_all (s_fact_action *action)
   s_fact_action *next;
   while (action) {
     next = action->next;
-    free(action);
+    alloc_unmap(action, sizeof(s_fact_action));
     action = next;
   }
 }
diff --git a/libkc3/facts_with_cursor.c b/libkc3/facts_with_cursor.c
index 7c4799c..5b2f059 100644
--- a/libkc3/facts_with_cursor.c
+++ b/libkc3/facts_with_cursor.c
@@ -134,9 +134,9 @@ s_fact ** facts_with_cursor_next (s_facts_with_cursor *cursor,
   *dest = fact;
   return dest;
  not_found:
-  cursor->facts_count = 0;
   alloc_unmap(cursor->levels, cursor->facts_count *
               sizeof(s_facts_with_cursor_level));
+  cursor->facts_count = 0;
   alloc_free(cursor->spec);
 #if HAVE_PTHREAD
   mutex_unlock(&cursor->mutex);
diff --git a/test/Makefile b/test/Makefile
index b71676b..bfeac6a 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -74,6 +74,9 @@ gcovr:
 gdb_test: debug
 	if [ -f libkc3_test_debug.core ]; then ${GDB} .libs/libkc3_test_debug libkc3_test_debug.core; else ${GDB} .libs/libkc3_test_debug; fi
 
+gdb_test_asan: asan
+	if [ -f libkc3_test_asan.core ]; then ${GDB} .libs/libkc3_test_asan libkc3_test_asan.core; else ${GDB} .libs/libkc3_test_asan; fi
+
 gdb_test_ekc3:
 	cd ekc3 && ${GDB} ../../kc3s/.libs/kc3s_debug