aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-17 14:30:33 +0200
committerBad Diode <bd@badd10de.dev>2021-10-17 14:30:33 +0200
commit953a44b3fd61302e6b86d549109a718a001c9b3c (patch)
treeb73d2d68b268bd3eb902e025d4a36a2095f3e3fd
parentdbeab0d63b21c14e9c462c08c8f776e9428b853c (diff)
downloadbdl-953a44b3fd61302e6b86d549109a718a001c9b3c.tar.gz
bdl-953a44b3fd61302e6b86d549109a718a001c9b3c.zip
Fix heap corruption bug due to bad initialization
-rwxr-xr-xMakefile6
-rw-r--r--src/bootstrap/environment.c1
-rw-r--r--src/bootstrap/gc.c41
-rwxr-xr-xsrc/bootstrap/main.c2
4 files changed, 28 insertions, 22 deletions
diff --git a/Makefile b/Makefile
index 50e0828..4465daf 100755
--- a/Makefile
+++ b/Makefile
@@ -15,12 +15,12 @@ BIN := $(BUILD_DIR)/$(TARGET)
15 15
16# Compiler and linker configuration. 16# Compiler and linker configuration.
17CC := cc 17CC := cc
18CFLAGS := -Wall -Wextra -pedantic -DBIN_NAME=\"$(TARGET)\" -static 18CFLAGS := -Wall -Wextra -pedantic -DBIN_NAME=\"$(TARGET)\"
19CFLAGS += $(INC_FLAGS) 19CFLAGS += $(INC_FLAGS)
20LDFLAGS := 20LDFLAGS :=
21LDLIBS := 21LDLIBS :=
22RELEASE_CFLAGS := -DNDEBUG -O2 22RELEASE_CFLAGS := -DNDEBUG -O2 -static
23DEBUG_CFLAGS := -DDEBUG -O2 -g 23DEBUG_CFLAGS := -DDEBUG -O0 -g -fsanitize=address
24 24
25.PHONY: build tests run clean 25.PHONY: build tests run clean
26 26
diff --git a/src/bootstrap/environment.c b/src/bootstrap/environment.c
index 570c5d4..d5e954b 100644
--- a/src/bootstrap/environment.c
+++ b/src/bootstrap/environment.c
@@ -21,6 +21,7 @@ Environment *
21env_create(Environment *parent) { 21env_create(Environment *parent) {
22 Environment *env = alloc_env(); 22 Environment *env = alloc_env();
23 env->parent = parent; 23 env->parent = parent;
24 env->marked = false;
24 env->buf = NULL; 25 env->buf = NULL;
25 env->size = 0; 26 env->size = 0;
26 env->cap = ENV_BUF_CAP; 27 env->cap = ENV_BUF_CAP;
diff --git a/src/bootstrap/gc.c b/src/bootstrap/gc.c
index 381ab6b..5f023bc 100644
--- a/src/bootstrap/gc.c
+++ b/src/bootstrap/gc.c
@@ -35,13 +35,9 @@ typedef struct GC {
35 ActiveEnvs active_envs; 35 ActiveEnvs active_envs;
36} GC; 36} GC;
37 37
38// FIXME: small value for testing purposes
39// #define GC_OBJS_CAP 1024 * 1024 * 10
40// #define GC_ROOTS_CAP 1024
41// #define GC_ENVS_CAP 1024 * 1024 * 2
42#define GC_OBJS_CAP 1024 * 1024 38#define GC_OBJS_CAP 1024 * 1024
43#define GC_ROOTS_CAP 1024 * 1024 39#define GC_ROOTS_CAP 1024
44#define GC_ENVS_CAP 1024 * 1024 40#define GC_ENVS_CAP 1024 * 4
45 41
46static GC gc; 42static GC gc;
47 43
@@ -82,7 +78,8 @@ void
82push_active_env(Environment *env) { 78push_active_env(Environment *env) {
83 if (gc.active_envs.size == gc.active_envs.cap) { 79 if (gc.active_envs.size == gc.active_envs.cap) {
84 gc.active_envs.cap *= 2; 80 gc.active_envs.cap *= 2;
85 gc.active_envs.buf = realloc(gc.active_envs.buf, gc.active_envs.cap * sizeof(Environment *)); 81 gc.active_envs.buf = realloc(gc.active_envs.buf,
82 gc.active_envs.cap * sizeof(Environment *));
86 } 83 }
87 gc.active_envs.buf[gc.active_envs.size++] = env; 84 gc.active_envs.buf[gc.active_envs.size++] = env;
88} 85}
@@ -148,9 +145,9 @@ mark_environment(Environment *env) {
148 } 145 }
149 env->marked = true; 146 env->marked = true;
150 for (size_t i = 0; i < env->size; i++) { 147 for (size_t i = 0; i < env->size; i++) {
151 EnvEntry entry = env->buf[i]; 148 EnvEntry *entry = &env->buf[i];
152 mark_obj(entry.symbol); 149 mark_obj(entry->symbol);
153 mark_obj(entry.value); 150 mark_obj(entry->value);
154 } 151 }
155} 152}
156 153
@@ -177,11 +174,7 @@ mark_and_sweep(void) {
177 for (size_t i = 0; i < gc.active_envs.size; i++) { 174 for (size_t i = 0; i < gc.active_envs.size; i++) {
178 mark_environment(gc.active_envs.buf[i]); 175 mark_environment(gc.active_envs.buf[i]);
179 } 176 }
180
181 for (size_t i = 0; i < gc.roots.size; i++) { 177 for (size_t i = 0; i < gc.roots.size; i++) {
182 if (gc.roots.buf[i]->marked) {
183 continue;
184 }
185 mark_obj(gc.roots.buf[i]); 178 mark_obj(gc.roots.buf[i]);
186 } 179 }
187 180
@@ -231,8 +224,7 @@ dump_gc(void) {
231 display(gc.roots.buf[i]); 224 display(gc.roots.buf[i]);
232 printf("\n"); 225 printf("\n");
233 } 226 }
234 printf("------------- OBJECTS ------------- \n"); 227 printf("--------- OBJECTS (TOP 20) -------- \n");
235 // for (size_t i = 0; i < gc.obj_cap; i++) {
236 for (size_t i = 0; i < 20; i++) { 228 for (size_t i = 0; i < 20; i++) {
237 printf("i: %ld -> ", i); 229 printf("i: %ld -> ", i);
238 Object *obj = &gc.objects[i]; 230 Object *obj = &gc.objects[i];
@@ -249,8 +241,20 @@ dump_gc(void) {
249 } 241 }
250 printf("\n"); 242 printf("\n");
251 } 243 }
252 printf("FREE OBJECTS: %ld\n", gc.free_objects.size); 244 printf("-------------- MISC --------------- \n");
253 printf("ENVIRONMENTS: %ld\n", gc.envs.size); 245 printf("gc.roots.size: %ld\n", gc.roots.size);
246 printf("gc.roots.cap: %ld\n", gc.roots.cap);
247 printf("gc.active_envs.size: %ld\n", gc.active_envs.size);
248 printf("gc.active_envs.cap: %ld\n", gc.active_envs.cap);
249 printf("gc.obj_cap: %ld\n", gc.obj_cap);
250 printf("gc.free_objects.size: %ld\n", gc.free_objects.size);
251 printf("gc.free_objects.cap: %ld\n", gc.free_objects.cap);
252 printf("gc.free_objects.position: %ld\n", gc.free_objects.position);
253 printf("gc.free_envs.size: %ld\n", gc.free_envs.size);
254 printf("gc.free_envs.cap: %ld\n", gc.free_envs.cap);
255 printf("gc.free_envs.position: %ld\n", gc.free_envs.position);
256 printf("gc.envs.size: %ld\n", gc.envs.size);
257 printf("gc.envs.cap: %ld\n", gc.envs.cap);
254} 258}
255 259
256Object * 260Object *
@@ -278,5 +282,6 @@ alloc_object(ObjectType type) {
278 gc.free_objects.size--; 282 gc.free_objects.size--;
279 Object *obj = get_obj(slot); 283 Object *obj = get_obj(slot);
280 obj->type = type; 284 obj->type = type;
285 obj->marked = false;
281 return obj; 286 return obj;
282} 287}
diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c
index 7251e60..bf2354b 100755
--- a/src/bootstrap/main.c
+++ b/src/bootstrap/main.c
@@ -115,10 +115,10 @@ process_source(const StringView *source) {
115 size_t root_stack_size = gc.roots.size; 115 size_t root_stack_size = gc.roots.size;
116 Object *root = parse_tree(&visitor); 116 Object *root = parse_tree(&visitor);
117 gc.roots.size = root_stack_size; 117 gc.roots.size = root_stack_size;
118 push_root(root);
119 if (root == obj_err || errors_n != 0) { 118 if (root == obj_err || errors_n != 0) {
120 break; 119 break;
121 } 120 }
121 push_root(root);
122 122
123 Object *result = eval(global_env, root); 123 Object *result = eval(global_env, root);
124 if (result != obj_nil) { 124 if (result != obj_nil) {