Core dump from cyrusdb_skiplist.c

Bron Gondwana brong at fastmail.fm
Mon Sep 8 21:11:36 EDT 2008


Yeah, you've got a corrupted skiplist file.  There are a variety
of reasons why this could be the case, but most of all, the
skiplist library in 2.3.7 is pretty buggy.  Well, no more buggy
than it had been for ages, but I got a LOT of fixes added since
then.

Probably the best skiplist library in current use is 2.3.11.  2.3.12
is theoretically better, but it actually exposes a bug that just
silently worked in 2.3.11.

Hopefully, if Wes and Ken are happy that the locking refactor is
tested enough, there will be a 2.3.13 soonish with a "perfect"
skiplist library.

Meanwhile - that doesn't fix your problem!  How attached are you
to the data in the skiplist file?  It's your annotations DB.  Do you have
a recent backup before it got corrupted?  It's sometimes hard to tell.

I can probably repair it for you, but I haven't got a good working
automated tool for it.  I'd be going in and fiddling the bits by hand!

Bron.


On Mon, 8 Sep 2008 16:07:41 +0200, "DEMBKOWSKI, Henryk (Henryk)" <hdembkowski at alcatel-lucent.com> said:
> Hi,  
> 
> 
> We are using cyrus-imapd-2.3.7 to store our messages.
> And we got core from imap - file cyrusdb_skiplist.c
> 
> 
> #0  myforeach (db=0x814b618, prefix=0xbfffb8c0 "user.6165602930",
> prefixlen=16, goodp=0x8087dc0 <find_p>,
>     cb=0x80871d0 <find_cb>, rock=0xbfffb8b0, tid=0xbfffc91c) at
>     cyrusdb_skiplist.c:1019
> 1019                    ptr = db->map_base + FORWARD(ptr, 0);
> (gdb) t 1
> [Switching to thread 1 (process 14237)]#0  myforeach (db=0x814b618,
> prefix=0xbfffb8c0 "user.6165602930", prefixlen=16,
>     goodp=0x8087dc0 <find_p>, cb=0x80871d0 <find_cb>, rock=0xbfffb8b0,
>     tid=0xbfffc91c) at cyrusdb_skiplist.c:1019
> 1019                    ptr = db->map_base + FORWARD(ptr, 0);
> (gdb) where
> #0  myforeach (db=0x814b618, prefix=0xbfffb8c0 "user.6165602930",
> prefixlen=16, goodp=0x8087dc0 <find_p>,
>     cb=0x80871d0 <find_cb>, rock=0xbfffb8b0, tid=0xbfffc91c) at
>     cyrusdb_skiplist.c:1019
> #1  0x08087ecf in annotatemore_findall (mailbox=0x814b618 "@&#351;\024\b\a",
> entry=0x80b4834 "*", proc=0x4effb8, rock=0x4effb8,
>     tid=0xbfffc91c) at annotate.c:391
> #2  0x0808801b in annotatemore_rename (oldmboxname=0xbfffd730
> "user.6165602930",
>     newmboxname=0x4effb8 <Address 0x4effb8 out of bounds>,
>     olduserid=0x4effb8 <Address 0x4effb8 out of bounds>,
>     newuserid=0x4effb8 <Address 0x4effb8 out of bounds>) at
>     annotate.c:2093
> #3  0x08055e39 in cmd_rename (tag=0x8151a28 "1", oldname=0x8151b08
> "user.6165602930", newname=0x81c6010 "user.6163078011",
>     partition=0x0) at imapd.c:5408
> #4  0x0805e3ac in cmdloop () at imapd.c:1532
> #5  0x08060a57 in service_main (argc=1, argv=0x8149008, envp=0xbffffd64)
> at imapd.c:789
> #6  0x0804c3a8 in main (argc=3, argv=0xbffffd54, envp=0xbffffd64) at
> service.c:532
> 
> 
> It refers to function myforeach() and code
> 
> 
>     980             /* save KEY, KEYLEN */
>     981             if (KEYLEN(ptr) > savebuflen) {
>     982                 savebuflen = KEYLEN(ptr) + 1024;
>     983                 savebuf = xrealloc(savebuf, savebuflen);
>     984             }
>     985             memcpy(savebuf, KEY(ptr), KEYLEN(ptr));
>     986             savebufsize = KEYLEN(ptr);
>     987
>     988             /* make callback */
>     989             cb_r = cb(rock, KEY(ptr), KEYLEN(ptr), DATA(ptr),
>     DATALEN(ptr));
>     990             if (cb_r) break;
>     991
>     992             if (!tid) {
>     993                 /* grab a r lock */
>     994                 if ((r = read_lock(db)) < 0) {
>     995                     return r;
>     996                 }
>     997             } else {
>     998                 /* make sure we're up to date */
>     999                 update_lock(db, tp);
>    1000             }
>    1001
>    1002             /* reposition */
>    1003             if (!(ino == db->map_ino && sz == db->map_size)) {
>    1004                 /* something changed in the file; reseek */
>    1005                 ptr = find_node(db, savebuf, savebufsize, 0);
>    1006
>    1007                 /* 'ptr' might not equal 'savebuf'.  if it's
>    different,
>    1008                    we want to stay where we are.  if it's the
>    same, we
>    1009                    should move on to the next one */
>    1010                 if (savebufsize == KEYLEN(ptr) &&
>    1011                     !memcmp(savebuf, KEY(ptr), savebufsize)) {
>    1012                     ptr = db->map_base + FORWARD(ptr, 0);
>    1013                 } else {
>    1014                     /* 'savebuf' got deleted, so we're now
>    pointing at the
>    1015                        right thing */
>    1016                 }
>    1017             } else {
>    1018                 /* move to the next one */
>    1019                 ptr = db->map_base + FORWARD(ptr, 0);
>    1020             }
>    1021         } else {
>    1022             /* we didn't make the callback; keep going */
>    1023             ptr = db->map_base + FORWARD(ptr, 0);
>    1024         }
>    1025     }
> 
> 
> 
> Do you know something about it?
> 
> 
> 
> Kind Regards,
> Henryk
-- 
  Bron Gondwana
  brong at fastmail.fm



More information about the Cyrus-devel mailing list