Segmentation fault in matcher/queryoptimiser
olly at survex.com
Mon Jul 31 22:29:25 BST 2017
On Mon, Jul 31, 2017 at 09:24:29AM +0200, Robert Stepanek wrote:
> Since a couple of weeks we are experiencing occasional segmentation
> faults within Xapian 1.5. We can't reproduce the crashes, but we have
> strong hints that they are due to memory corruption. We have narrowed
> down our root cause analysis to phrase searches on multi-databases that
> fail on reading the `hint` field in the`QueryOptimiser`class .
> We'd appreciate any hints on how to fix this. I've written up our
> findings and solution attempts below. Should we post this on trac?
Yes, it'd be good to have a ticket to track this.
> In a core dump we see that calling the `open_nearby_postlist` function
> on the `hint` variable  falls of a cliff, resulting in a segfault:
This mechanism is mainly there to speed up wildcard expansion - in this
case we look up a slew of terms in sorted order that will be close to
each other, so we cache the PostList object from the previous term and
use that as a hint for where to start looking to find the next term.
Although it's mainly for wildcards, this mechanism is actually in place
for all PostList lookups that happen when a query is run, as other
situations can benefit too.
> Here is what I believe is happening:
> We are using subdatabases (all glass) for caching recent database
> additions, and some of these do not contain positional information. This
> makes the internal query code reset the AND-context, which in effect
> frees its postlist. One of the postlist entries is still pointed at by
> the `hint` field of QueryOptimiser from a previous submatch, and the
> next call to `get_hint_postlist` in queryoptimiser.h#L106 references the
> bogus address.
That sounds very plausible.
> A fix to avoid this is simple: just reset the QueryOptimiser hint field
> when free'ing the context postlist. I've written a one-liner for this
> here .
At first impression this seems a bit crude as we don't know that the
hint is affected, but in practical terms I suspect it's rare that it
matters, and it is at least a simple approach.
> But I'm not yet convinced that's all there is: could the hint
> field be used already somewhere else?
I'll have to remind myself how this works in more detail to say for sure
if it could be used elsewhere, but I suspect it can't be.
> Should we probably keep it and make QueryOptimiser take ownership?
That's exactly how I fixed a similar earlier issue (see commit
We should probably address both issues consistently. If setting the hint
to NULL works, we should probably evaluate that approach as it avoids
the overhead of tracking ownership and of checking if we're about to
delete the current hint.
The code that's causing the problem was added in commit
7a4d4f5f597aba1c625014220856fe5bc786bcc0 which was backported for
1.4.3, so I'd expect this also affects 1.4.3.
More information about the Xapian-devel