RHEL5 x64, skiplist statuscache SIGV
Michael Glad
glad at daimi.au.dk
Mon Sep 24 04:26:11 EDT 2007
The problems seem to boil down to what happens when one tries to delete
a key from an empty skiplist db:
bash-3.00$ touch /tmp/foo.db
bash-3.00$ /usr/lib/cyrus-imapd/cyr_dbtool /tmp/foo.db skiplist show
bash-3.00$ ls -l /tmp/foo.db
-rw-r--r-- 1 cyrus mail 144 Sep 24 10:03 /tmp/foo.db
bash-3.00$ /usr/lib/cyrus-imapd/cyr_dbtool /tmp/foo.db skiplist delete bar
Segmentation fault
This was done on RHEL4/x32. The same happens on RHEL5/x64.
As I wrote below, it seems that the skiplist code in this case tries to
extract skiplist pointers from the db header.
- Michael
On Mon, Sep 24, 2007 at 12:25:55PM +1000, Bron Gondwana wrote:
>
> On Sun, 23 Sep 2007 21:58:57 +0200, "Michael Glad" <glad at daimi.au.dk> said:
> >
> > Hello Bron, I've tested Cyrus 2.3.9 + your FM patches as of September 20
> > on a RHEL5 x64 Opteron virtual machine.
>
> We don't have any experience (yet) with 64 bit. I believe it's less
> well tested.
>
> > As I'm a BDB skepticist I use skiplists where ever possible including
> > the statuscache.
>
> >From memory it's not a good match because of the various strengths and
> weaknesses of the the database methods used. Skiplist is good for heavy
> read loads, not so good for heavy write loads.
>
> > But Imapd SIGV's in the skiplist mydelete routine (invoked from
> > statuscache_invalidate) when the first 'select INBOX' command is
> > received.
> >
> > I've looked into the cause and would to hear your opinion before I
> > post the info below to the devel list.
> >
> > It seems to me that the skiplist routine is to blame. The SIGV
> > arises from line 1305:
> >
> > newoffset = htonl(FORWARD(ptr, i));
> >
> > But ptr at the time of the crash points to db->map_base which is the
> > initial skiplist header => Kaboom.
> >
> > When I apply the patch:
> >
> > @@ -1292,6 +1292,11 @@
> > ptr = find_node(db, key, keylen, updateoffsets);
> > if (ptr == db->map_base ||
> > !db->compar(KEY(ptr), KEYLEN(ptr), key, keylen)) {
> > +/* start glad */
> > +if(ptr == db->map_base) {
> > + ptr = DUMMY_PTR(db);
> > +}
> > +/* end glad */
> > /* gotcha */
> > offset = ptr - db->map_base;
> >
> > things doesn't SIGV and output from
> >
> > /usr/lib/cyrus-imapd/cyr_dbtool /var/lib/imap/statuscache.db skiplist show
> >
> > looks sensible -- it is partly garbled on my nonpatched RHEL4
> > x32 production system.
>
>
> I have CC'd this to the cyrus development list, as there are probably people with
> more skiplist and 64 bit programming experience who can tell you if this is the
> right approach, and hopefully push the fix into the next Cyrus release!
>
> Bron.
> --
> Bron Gondwana
> brong at fastmail.fm
More information about the Cyrus-devel
mailing list