[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