-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
caution: that's quite a lot of speculation. I would suggest checking first to see if the crash doesn't happen if there's > 1 eval call involved, if there's multiple procedures, if SpamAssassin isn't in the picture etc.; there are several possible workarounds, depending on what exactly is causing the bug. Me, I'd start trying to repro without SpamAssassin involved. if it's crashing in Perl_malloc() from functions in hv.c, that's some very generic core-perl code it's crashing in. - --j. Loren Wilton writes: > > The line in $evalstr that causes the stack fault is: > > > > if ($self->{conf}->{scores}->{q{WLS_URI_OPT_377}}) { > > > > Which is on line 21720 (out of ~30800 lines). From what I've gathered, > each > > rule in the .cf files results in 4 lines being strung together in > $evalstr: > > > > if ($self->{conf}->{scores}->{q{<RULE_NAME>}}) { > > <RULE_NAME>_uri_test($self, @_); # call procedurally for speed > > } > > > > It doesn't matter which rule is on line 21720 (as I've changed them around > > to make sure it wasn't specifically WLS_URI_OPT_377, from > > sa-blacklist.current.uri.cf), It seems when you get to line 21720 w/ a > 64MB > > stack on FreeBSD 5.4 w/ perl 5.8.7 etc, etc. that you've ran out of stack > > space. This is part of the gdb bt from a perl5.8.7.core that I had: > > > > #0 0x280a2144 in Perl_malloc (nbytes%) at malloc.c:1411 > > #1 0x281075b5 in S_save_hek_flags (str=0x935b328 "WLS_URI_OPT_377", > len, > > hash20016264, flags=0) at hv.c:97 > etc. > > Ok. This sounds to me like a perl bug that can probably be worked around. > It is dying in malloc, apparently trying to malloc heap data on the stack, > which gcc tends to do a lot. Since it happens on the same line in the file > regardless of which rule is there, it is happening at the same 'call a rule' > number in the procedure containing the calls to the rules. > > So the first useful question is to convert that line number to a rule call > number in the containing procedure. Subtract the line number for the first > one of those 'if ($self...' lines from the failing line, and then divide by > 4 to convert line numbers into rule counts. (Assuming there are 4 lines > including a blank line, else divide by 3.) > > Once that number is known, I suspect the trivial (but somewhat ugly) change > is to maintain a count in sa of the number of rules being generated, and > split the rule calling procedure into multiple procedures every N rules, > where N is some small number (16 or so) less than the number you compute > above. Then generate a final wrapper procedure that will call all of these > split procedures. > > The end result will be one extra level of call to evaluate the rules, but > the procedure flipping will probably be fairly rare (I'm assuming there will > be several hundred rules per sub-procedure), so there won't be any noticible > change in performance. And the erroneous heap buildup will disappear each > time one of the sub-procedures is exited. > > A possible second workaround is to try to figure out what hash it is that > Perl seems to be setting flags in as it is calling the rules. I don't see > it obviously in the code; but then I don't really read Perl, and it may be > obvious to someone else. If this is obvious, there may be some trivial code > formatting change that will unconvince Perl that it needs to be mucking with > the hash in the first place. > > And of course I'd be inclined to supply the 1MB file as a bug attachment to > perl, explaining that it blows stack on BSD and works fine everywhere else. > However, that is likely a longer-term fix than changing the rule generating > code to build a second level of calling procedure and segment the rule calls > into multiple procedures. > > Loren -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (GNU/Linux) Comment: Exmh CVS iD8DBQFC5uvJMJF5cimLx9ARAmQEAJ44fLprEfzM85enQmlC5fOicdCqIQCgmNff OlZfoCtME/5wl0OswzVtmhA= =JDGi -----END PGP SIGNATURE-----