Mailing List Archive

QueryFilter Crashings and Smashings
I am getting this error lately ... any clues?

Error in function refill at ../c_src/KinoSearch/Store/InStream.c:92: Read
past EOF of _1.p1 (start: 0 len 912) at
/usr/local/lib/perl5/site_perl/5.8.4/darwin-2level/KinoSearch/Searcher.pm
line 122

This happens on a call to ->search with a QueryFilter passed for the filter
parameter. It's a bunch of Index::Term objects MUST'd together in a
BooleanQuery.

The second time through, though, it works: the first time I call ->search,
the above error is produced, but something happens with the QueryFilter so
that it works the second time through. Dumping the object, I notice that
cached_bits is populated before the second call, and it was empty on the
first call. That's the only obvious difference.

Now using the same BooleanQuery that I created the QueryFilter from, and
passing that as the query parameter. It crashes too, but now it doesn't
work on subsequent attempts, as the QueryFilter did.

The BooleanQuery itself is hard to pin down. I have these terms:

uid => 2,
accepted => 'no',
rejected => 'no',
public => 'yes',
editorpop => 25,
category => 'none'

If I do just the first two, it works. The first three, it doesn't. If I
remove just the first one and do the other five, it works. And so on.

I hope that information is enough to help you recognize the problem; if
not, I can try to provide more detail.

--
Chris Nandor pudge@pobox.com http://pudge.net/
Slashdot / SourceForge pudge@slashdot.org http://slashdot.org/
QueryFilter Crashings and Smashings [ In reply to ]
On May 31, 2007, at 11:05 PM, Chris Nandor wrote:

> The second time through, though, it works: the first time I call -
> >search,
> the above error is produced, but something happens with the
> QueryFilter so
> that it works the second time through. Dumping the object, I
> notice that
> cached_bits is populated before the second call, and it was empty
> on the
> first call. That's the only obvious difference.

I think "works" and "populated" may be misleading here. I assume
you're running these inside an eval, because otherwise you'd never
get to a "second time through". In the QueryFilter code, the cached
BitVector is stored via QueryFilter->store_cached_bits before
Searcher->collect is run to actually flip the bits. It's the call to
Searcher->collect that's crashing. The QueryFilter code is not to
blame.

> Now using the same BooleanQuery that I created the QueryFilter
> from, and
> passing that as the query parameter. It crashes too, but now it
> doesn't
> work on subsequent attempts, as the QueryFilter did.
>
> The BooleanQuery itself is hard to pin down. I have these terms:
>
> uid => 2,
> accepted => 'no',
> rejected => 'no',
> public => 'yes',
> editorpop => 25,
> category => 'none'
>
> If I do just the first two, it works. The first three, it
> doesn't. If I
> remove just the first one and do the other five, it works. And so on.

Since you indicate that these are all added to your BooleanQuery with
'MUST', the final BooleanScorer will be a thin wrapper around an
ANDScorer with several TermScorers as its subscorers.

I suspect that the problem will be found within ANDScorer_skip_to().
There's probably an extra call to a subscorer's Scorer_Skip_To() or
Scorer_Doc() methods after that subscorer has been exhausted. (Once
Scorer_Next returns false, it's invalid to call either Scorer_Skip_To
or Scorer_Doc.) In the effort to make that code as efficient as
possible, it came out a mite tortured.

Fixing it will take an effort similar to what it took to fix
BitVec_Flip_Range. The function should be rethought and simplified
if possible. It will also need more aggressive tests. The bug
you're seeing now isn't revealed by the test suite because it depends
on a peculiar sequence of document numbers within the subscorers.
Hopefully we can come up with a pattern that covers more possible
combinations.

I'll try to get to this this weekend. In the meantime, if you want
to scratch the itch, throw in a couple debug "Warn" calls and see if
you can isolate the failing line within ANDScorer_skip_to.

Marvin Humphrey
Rectangular Research
http://www.rectangular.com/
QueryFilter Crashings and Smashings [ In reply to ]
On Jun 1, 2007, at 1:42 PM, Marvin Humphrey wrote:

> I suspect that the problem will be found within ANDScorer_skip_to().

OK, I took a shot at this and couldn't find any flaws in the
ANDScorer_skip_to algo. I'll need more info.

(You haven't changed up any of the field defs, have you?)

Please update to the latest repository revision -- the error messages
in InStream were using a 64-bit integer that Perl's sv_catpvf
couldn't handle, and "start: 0" is probably wrong.

Error in function refill at ../c_src/KinoSearch/Store/InStream.c:
92: Read
past EOF of _1.p1 (start: 0 len 912) at
/usr/local/lib/perl5/site_perl/5.8.4/darwin-2level/KinoSearch/
Searcher.pm
line 122

_1.p1 is a postings file for field number 1 in segment _1. I'd like
to know what the file length is for _1.p1, and what field corresponds
to field 1 in segment _1. All that information can be found in the
latest segments_XXX.yaml file. If there's no proprietary info in the
segments file, please consider pasting its contents into an email so
we can examine it.

It would be useful to know if it's the same field at the same spot
erroring out over and over or if the locus changes.

The only thing which could be reading the _1.p1 file is a TermScorer
subclass in the midst of scoring. We need to know exactly what
aspect of scoring is triggering the glitch. Unfortunately, the stack
traces yielded by the CONFESS macro only contain the Perl call stack,
not the C stack -- so we have to go hunting.

Marvin Humphrey
Rectangular Research
http://www.rectangular.com/
QueryFilter Crashings and Smashings [ In reply to ]
At 18:53 -0700 2007.06.01, Marvin Humphrey wrote:
>On Jun 1, 2007, at 1:42 PM, Marvin Humphrey wrote:
>
>> I suspect that the problem will be found within ANDScorer_skip_to().
>
>OK, I took a shot at this and couldn't find any flaws in the
>ANDScorer_skip_to algo. I'll need more info.
>
>(You haven't changed up any of the field defs, have you?)

No, it was a new index.


>It would be useful to know if it's the same field at the same spot
>erroring out over and over or if the locus changes.

How could I tell that? Just from re-running with the updates to those two
C files?


It seems like I get the same spot each time, even if I change the terms
(though I have not tried every possible combination):

Error:Slash::SearchToo::Kinosearch:/usr/local/lib/perl5/site_perl/5.8.4/Slash/SearchToo/Kinosearch.pm:215:21052:
kinosearcher failed (attempt 1). Trying again ... : Error in function
refill at ../c_src/KinoSearch/Store/InStream.c:92: Read past EOF of _1.p1
(start: 912 len 912)

--
Chris Nandor pudge@pobox.com http://pudge.net/
Slashdot / SourceForge pudge@slashdot.org http://slashdot.org/
QueryFilter Crashings and Smashings [ In reply to ]
On Jun 4, 2007, at 9:18 AM, Chris Nandor wrote:

> Error:Slash::SearchToo::Kinosearch:/usr/local/lib/perl5/site_perl/
> 5.8.4/Slash/SearchToo/Kinosearch.pm:215:21052:
> kinosearcher failed (attempt 1). Trying again ... : Error in function
> refill at ../c_src/KinoSearch/Store/InStream.c:92: Read past EOF of
> _1.p1
> (start: 912 len 912)

I believe I've finally got this bug hunted and killed, though I'll
have to wait for official confirmation from you, Pudge. In any case,
I've found something that can result in both crashes and incorrect
search results. It's sufficiently nasty that I'm going to release
version 0.20_04 ASAP.

This bug had both search-time and index-time components. Indexes
created with 0.20_03 are probably corrupt; however, they need not be
recreated from scratch. It is only the .skip file which contains bad
information, and this gets completely regenerated for each new
segment. To repair existing indexes, optimize them to a single, new
segment:

$invindexer->finish( optimize => 1 );

Details:

Your query produced a BooleanScorer with several TermScorers. These
TermScorers iterate over document numbers using PostingList objects.

SegPList_skip_to() was not living up to its contract. It is supposed
to be an optimization of PList_skip_to, but it was malfunctioning and
setting the SegPostingList object's internal state incorrectly. It
was both seeking to the wrong place in the .p1 postings file, and
setting the count of docs already seen to an incorrect, lower number.

The crash you saw arose because of the counting issue -- the iterator
kept going after it should have quit, resulting in the "Read past EOF".

However, this bug can also result in search results which are simply
incorrect. After an optimized seek, the SegPostingList object is
reading from the wrong place in the postings file. It will now read
incorrect delta doc numbers, and produce bogus matches. The larger
the index, the more wrong results you're likely to see.

The crucial component of the fix was a set of stress tests for
SegPList_skip_to. Once they were in place, the necessary fixes in
PostingsWriter.c and SegPostingList.c could be identified.

Marvin Humphrey
Rectangular Research
http://www.rectangular.com/
QueryFilter Crashings and Smashings [ In reply to ]
At 14:15 -0700 2007.06.20, Marvin Humphrey wrote:
>I believe I've finally got this bug hunted and killed, though I'll
>have to wait for official confirmation from you, Pudge.

I just worked on it today, and am unable to make it crash, and I get the
results I expect. Looks good to me!

--
Chris Nandor pudge@pobox.com http://pudge.net/
Slashdot / SourceForge pudge@slashdot.org http://slashdot.org/
QueryFilter Crashings and Smashings [ In reply to ]
On Wed, 20 Jun 2007, Marvin Humphrey wrote:

> ... To repair existing indexes, optimize them to a single, new
> segment:
>
> $invindexer->finish( optimize => 1 );

Instead of stepping through all existing temp indexes and optimizing them,
would an optimize on a master index after merging the ("dirty") temps
perform the same repair (on the master)?

That way, I can not worry about the temps until they are re-indexed during
the next global indexing cycle.

?

Regards
Henry
QueryFilter Crashings and Smashings [ In reply to ]
On Jun 21, 2007, at 2:26 AM, Henk - CityWEB wrote:

> On Wed, 20 Jun 2007, Marvin Humphrey wrote:
>
>> ... To repair existing indexes, optimize them to a single, new
>> segment:
>>
>> $invindexer->finish( optimize => 1 );
>
> Instead of stepping through all existing temp indexes and
> optimizing them,
> would an optimize on a master index after merging the ("dirty") temps
> perform the same repair (on the master)?

Yes, that will work fine.

Marvin Humphrey
Rectangular Research
http://www.rectangular.com/