ref: 9d8f5a14662f6500c21ac4fa0afd083fc9e2467a
parent: 6b146c70c2863bf1e9d5c4a35cbd8426c5a161e7
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Feb 8 20:37:05 EST 2014
acid: fix memory corruption due to gc we cannot call gc() in execute() because it will gc anonyous intermediate results which happens when we construct a list and the elements are calculated by calling a function thru ocall() which calls execute(). also, the _thiscmd symbol; which is used to keep a reference to a statement so it wont get garbage collected; does not work as yyparse() is recursive (include statements). we add execrec() function which *only* gets called from yyparse() when evaluating a statement. it will keep a stack on the _thiscmd symbol handling the yyparse() recursion. we also only call gc() in execrec() before calling execute(). so execute() will never gc() while evaluating a statement which prevents the intermediate results from getting collected.
--- a/sys/src/cmd/acid/acid.h
+++ b/sys/src/cmd/acid/acid.h
@@ -190,6 +190,7 @@
Lsym* enter(char*, int);
void error(char*, ...);
void execute(Node*);
+void execrec(Node*);
void fatal(char*, ...);
void flatten(Node**, Node*);
void gc(void);
--- a/sys/src/cmd/acid/dbg.y
+++ b/sys/src/cmd/acid/dbg.y
@@ -50,11 +50,7 @@
bigstmnt : stmnt
{
- /* make stmnt a root so it isn't collected! */
- mkvar("_thiscmd")->proc = $1;
- execute($1);
- mkvar("_thiscmd")->proc = nil;
- gc();
+ execrec($1);
if(interactive)
Bprint(bout, "acid: ");
}
--- a/sys/src/cmd/acid/exec.c
+++ b/sys/src/cmd/acid/exec.c
@@ -57,6 +57,32 @@
}
void
+execrec(Node *n)
+{
+ Value *v;
+ Lsym *s;
+
+ /* make node a root so it isn't collected! */
+ s = mkvar("_thiscmd");
+
+ v = gmalloc(sizeof(Value));
+ memset(v, 0, sizeof(Value));
+ v->type = TCODE;
+ v->cc = n;
+ v->pop = s->v;
+
+ s->v = v;
+ s->proc = n;
+
+ gc();
+ execute(n);
+
+ s->proc = s->v->cc;
+ s->v = v->pop;
+ free(v);
+}
+
+void
execute(Node *n)
{
Value *v;
@@ -66,7 +92,6 @@
Node res, xx;
static int stmnt;
- gc();
if(gotint)
error("interrupted");
--- a/sys/src/cmd/acid/lex.c
+++ b/sys/src/cmd/acid/lex.c
@@ -569,11 +569,11 @@
s->lexval = t;
v = gmalloc(sizeof(Value));
- s->v = v;
-
+ memset(v, 0, sizeof(Value));
v->fmt = 'X';
v->type = TINT;
- memset(v, 0, sizeof(Value));
+
+ s->v = v;
return s;
}