summaryrefslogtreecommitdiffstats
path: root/stream.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-13 19:42:27 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-13 19:42:27 -0700
commit657c6fedce9c743e46badcc4457a1fbaa8901d7e (patch)
tree6ddef38e3dfa8cca28240b7ea505277db57ced15 /stream.c
parent9bed01c59d5f5fe0bbc9d025ae95cf3b9518d5a7 (diff)
downloadtxr-657c6fedce9c743e46badcc4457a1fbaa8901d7e.tar.gz
txr-657c6fedce9c743e46badcc4457a1fbaa8901d7e.tar.bz2
txr-657c6fedce9c743e46badcc4457a1fbaa8901d7e.zip
bugfix: gc-incorrect creation of catenated stream.
* stream.c (make_catenated_stream): Fix incorrect order of operations: list of streams stored into a structure that is not yet visible to the garbage collector. (Rules for coding this properly are explained in HACKING.) This was found by running a test with --gc-debug on 64 bit Darwin. The read_eval_stream function calls make_catenated_stream with an argument that is freshly constructed in the argument expression itself, triggering the issue.
Diffstat (limited to 'stream.c')
-rw-r--r--stream.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/stream.c b/stream.c
index b34da981..398feaf6 100644
--- a/stream.c
+++ b/stream.c
@@ -2343,9 +2343,12 @@ static struct strm_ops cat_stream_ops =
val make_catenated_stream(val stream_list)
{
struct cat_strm *s = coerce(struct cat_strm *, chk_malloc(sizeof *s));
+ val catstrm = nil;
strm_base_init(&s->a);
+ s->streams = nil;
+ catstrm = cobj(coerce(mem_t *, s), stream_s, &cat_stream_ops.cobj_ops);
s->streams = stream_list;
- return cobj(coerce(mem_t *, s), stream_s, &cat_stream_ops.cobj_ops);
+ return catstrm;
}
val make_catenated_stream_v(struct args *streams)