summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog21
-rw-r--r--lib.c19
-rw-r--r--lib.h2
-rw-r--r--txr.c14
4 files changed, 35 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 5dcad00e..7836e807 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2009-11-01 Kaz Kylheku <kkylheku@gmail.com>
+
+ Bug ID 27899: Garbage collection problem: method of locating stack
+ bottom is unreliable due to the unpredictable allocation order of local
+ variables. The addresses of stack_bottom_0 and stack_bottom_1 variables
+ do not necessarily bracket the others which means that some local
+ variables in main can be out of the reach of the garbage collector:
+ our stack bottom is wrongly in the middle of the frame.
+
+ * lib.c (init): Removed one of the stack bottom parameters, so there
+ is only one. This is passed straight down to gc_init.
+ Also noticed that the oom_realloc variable was not being set
+ from the oom parameter.
+
+ * lib.h (init): Declaration updated.
+
+ * txr.c (txr_main): New static function.
+ (main): Calls init, and then txr_main. The idea is that txr_main
+ should get fresh stack frame. So the stack_bottom variable in main
+ should be outside of that stack frame.
+
2009-10-22 Kaz Kylheku <kkylheku@gmail.com>
* lib.c (equal): Fix broken LSTR and FUN cases.
diff --git a/lib.c b/lib.c
index 3554264d..5694b9a1 100644
--- a/lib.c
+++ b/lib.c
@@ -1949,26 +1949,13 @@ void obj_pprint(obj_t *obj, obj_t *out)
}
void init(const char *pn, void *(*oom)(void *, size_t),
- obj_t **maybe_bottom_0, obj_t **maybe_bottom_1)
+ obj_t **stack_bottom)
{
- int growsdown;
- obj_t *local_bottom = nil;
progname = pn;
int gc_save = gc_state(0);
- /* If the local_bottom variable has a smaller address than
- either of the two possible top variables from
- the initializing function, then the stack grows
- downward in memory. In that case, we take the
- greater of the two values to be the top.
- Otherwise we take the smaller of the two values. */
-
- growsdown = &local_bottom < maybe_bottom_0;
-
- gc_init(growsdown
- ? max(maybe_bottom_0, maybe_bottom_1)
- : min(maybe_bottom_0, maybe_bottom_1));
-
+ oom_realloc = oom;
+ gc_init(stack_bottom);
obj_init();
uw_init();
stream_init();
diff --git a/lib.h b/lib.h
index 81ef1dce..45b454f5 100644
--- a/lib.h
+++ b/lib.h
@@ -312,7 +312,7 @@ obj_t *sort(obj_t *list, obj_t *lessfun, obj_t *keyfun);
void obj_print(obj_t *obj, obj_t *stream);
void obj_pprint(obj_t *obj, obj_t *stream);
void init(const char *progname, void *(*oom_realloc)(void *, size_t),
- obj_t **maybe_bottom_0, obj_t **maybe_bottom_1);
+ obj_t **stack_bottom);
void dump(obj_t *obj, obj_t *stream);
obj_t *snarf(obj_t *in);
obj_t *match(obj_t *spec, obj_t *data);
diff --git a/txr.c b/txr.c
index b2097b82..d369816f 100644
--- a/txr.c
+++ b/txr.c
@@ -133,17 +133,23 @@ obj_t *remove_hash_bang_line(obj_t *spec)
}
}
+static int txr_main(int argc, char **argv);
+
int main(int argc, char **argv)
{
- obj_t *stack_bottom_0 = nil;
+ obj_t *stack_bottom = nil;
+ progname = argv[0] ? argv[0] : progname;
+ init(progname, oom_realloc_handler, &stack_bottom);
+ return txr_main(argc, argv);
+}
+
+static int txr_main(int argc, char **argv)
+{
obj_t *specstring = nil;
obj_t *spec = nil;
obj_t *bindings = nil;
int match_loglevel = opt_loglevel;
progname = argv[0] ? argv[0] : progname;
- obj_t *stack_bottom_1 = nil;
-
- init(progname, oom_realloc_handler, &stack_bottom_0, &stack_bottom_1);
protect(&spec_file_str, 0);