[EMAIL PROTECTED] wrote:
Hmm, so this is (kind of) akin to the regcomp fix - it is the "new" stuff
that is in yyl?val that should be free-d. And it is worse than that
as yyl?val is just the topmost the parser state, so if I understand correctly
it isn't only their current values, but also anything that is in the
parser's stack (ysave-yyvs) at the time-of-death that needs to go.
And all of those use the horrid yacc-ish YYSTYPE union, so we don't know
what they are. Yacc did, it had a table which mapped tokens to types
which it used to get union assigns right. But byacc does not put that info
anywhere for run-time to use, so to get it right we would need to
re-process perly.y and then look at the state stack as we popped it.
Yup - that's about the size of it.
Yugh.
The way I usually do this is make YYSTYPE an "object" or something
like a Pascal variant record - which has a tag.
That was my idea - I just couldn't figure out any clean way of capturing
the type information. If only byacc had a $$type variable as well as $$
etc...
This would not be easy to fix for perl5.
The best I can come up with is to make them all OP *, inventing
special parse-time-only "ops" which can hold ival/pval/gvval values.
Then yydestruct could just free the ops in yylval and yyvs[],
freeing a gvalOP or pvalOP would do the right thing.
Almost certainly far more than we want to do to the maint branch.
That seems workable, although as you say, far too radical for the maint
branch :-(
The other way this mess is handled is to use a "slab allocator"
e.g. GCC used an "obstack" - this allows all the memory allocated
since one noted a "checkpoint" to be free-d.
One could fake that idea by making malloc "plugable" and plugging
it during parse to build a linked list or some such.
Well, that's kinda what we have with the scope stack, the problem is
that you don't know the type of the thing that needs freeing.
The down side of that scheme is that auxillary allocators tend to
upset Purify like tools almost as much as memory leaks do.
I've tried 2 approaches to this. The first is to add "#ifdef PURIFY"
code to pp_ctl.c along the lines of the following:
S_doeval(...)
{
...
/* Flush any existing leaks to the log */
purify_new_leaks();
...
if (yyparse() == failed) {
...
/* Ignore any leaks */
purify_clear_leaks();
}
...
}
However I'm still suspicious of this because of the number of leaks that
only appear when S_doeval is somewhere in the stack trace.
The other approach is to postprocess the purify log and ignore anything
that has S_doeval or Perl_pp_entereval in the stack. That's the
approach I'm currently using, but of course it ignores any real leaks
that coincidentally appear within an eval. I think I'll try getting rid
of as many leaks as possible under this restricted regime - even with
this restriction, and with the bugs I've already fixed the test suite
contains 141 memory errors.
The truth of the matter is that I suspect eval and die will always leak
until it is re-architected in perl6 - whenever that might be.
Alan Burlison