[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: (ITS#8819) LMDB seg fault with MDB_DUPSORT on -O3

hyc@symas.com wrote:
> github@nicwatson.org wrote:
>> Full_Name: Nic Watson
>> Version: LMDB v 0.9.21
>> OS: Ubuntu 17.04
>> URL: ftp://ftp.openldap.org/incoming/
>> Submission from: (NULL) (
>> I'm getting a seg fault in using LMDB on a database opened with MDB_DUPSORT.
>> Here's a minimal set of operations that will cause the problem:
>> It will *not* crash under debug.  In fact, -O3 -fvect-cost-model=cheap will
>> *not* crash.  This makes some sense since it is crashing on an SSE instruction.
>> I tried gcc versions (Ubuntu 7.2.0-8ubuntu3.2) and (Ubuntu 6.4.0-8ubuntu1) with
>> the same result.  I also tried with the mdb.master branch (0.9.70) with the same
>> result.
>> I'm not convinced this a fault in your code.  It may be a gcc bug.
> Interesting. I've got gcc 5.4.0 on Ubuntu 16.04 here, and no crash. Also
> rather puzzled that there's anything vectorizable in this code, that seems
> pretty unlikely.
I take it back - was able to reproduce the crash with gcc 5.4.0.

The crash is on this instruction

    0x000000000040f26b <+4235>:	add    $0x1,%edi
=> 0x000000000040f26e <+4238>:	movdqa (%rax,%rdx,1),%xmm1
    0x000000000040f273 <+4243>:	mov    (%rsp),%rax
    0x000000000040f277 <+4247>:	paddw  %xmm0,%xmm1

movdqa's description is "Move aligned packed integer values" and the values 
here are not aligned.

(gdb) bt
#0  0x000000000040f26e in mdb_cursor_put (mc=mc@entry=0x7fffffffdd00, 
key=key@entry=0x7fffffffe0e0, data=data@entry=0x7fffffffe1c0, 
flags=flags@entry=0) at mdb.c:7673
#1  0x0000000000411d64 in mdb_cursor_put (flags=0, data=0x7fffffffe1c0, 
key=0x7fffffffe0e0, mc=0x7fffffffdd00) at mdb.c:9867
#2  mdb_put (txn=0x61e680, dbi=2, key=key@entry=0x7fffffffe0e0, 
data=data@entry=0x7fffffffe1c0, flags=flags@entry=0) at mdb.c:9868
#3  0x0000000000401c13 in cause_crash () at its8819.c:53
#4  0x0000000000401991 in main (argc=<optimized out>, argv=<optimized out>) at 
(gdb) l
7668						memcpy(METADATA(mp), METADATA(fp), NUMKEYS(fp) * fp->mp_pad);
7669					} else {
7670						memcpy((char *)mp + mp->mp_upper + PAGEBASE, (char *)fp + 
fp->mp_upper + PAGEBASE,
7671							olddata.mv_size - fp->mp_upper - PAGEBASE);
7672						for (i=0; i<NUMKEYS(fp); i++)
7673							mp->mp_ptrs[i] = fp->mp_ptrs[i] + offset;
7674					}
7675				}
7677				rdata = &xdata;

In particular, the fp pointer is on an odd address. Basically the movdqa 
instruction is not valid for use here.

   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/