[erlang-bugs] Segmentation fault with ETS bag implementation in 64-bit Erlang

Sverker Eriksson sverker@REDACTED
Wed Feb 22 18:49:17 CET 2012


Yes, a fix will be released as part of R15B01.

Actually, the preliminary patch that I sent earlier was not complete. 
Integers larger than (1 bsl 55) may still provoke the same bug. Here is 
a better patch:

diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c
index 976f05c..25ac790 100644
--- a/erts/emulator/beam/big.c
+++ b/erts/emulator/beam/big.c
@@ -1844,6 +1844,7 @@ dsize_t big_bytes(Eterm x)
 /*
 ** Load a bignum from bytes
 ** xsz is the number of bytes in xp
+** *r is untouched if number fits in small
 */
 Eterm bytes_to_big(byte *xp, dsize_t xsz, int xsgn, Eterm *r)
 {
@@ -1852,7 +1853,7 @@ Eterm bytes_to_big(byte *xp, dsize_t xsz, int 
xsgn, Eterm *r)
     ErtsDigit d;
     int i;

-    while(xsz >= sizeof(ErtsDigit)) {
+    while(xsz > sizeof(ErtsDigit)) {
        d = 0;
        for(i = sizeof(ErtsDigit); --i >= 0;)
            d = (d << 8) | xp[i];
@@ -1867,11 +1868,20 @@ Eterm bytes_to_big(byte *xp, dsize_t xsz, int 
xsgn, Eterm *r)
        d = 0;
        for(i = xsz; --i >= 0;)
            d = (d << 8) | xp[i];
+       if (++rsz == 1 && IS_USMALL(xsgn,d)) {
+           if (xsgn) d = -d;
+           return make_small(d);
+       }
        *rwp = d;
        rwp++;
-       rsz++;
     }
-    return big_norm(r, rsz, (short) xsgn);
+    if (xsgn) {
+      *r = make_neg_bignum_header(rsz);
+    }
+    else {
+      *r = make_pos_bignum_header(rsz);
+    }
+    return make_big(r);
 }

 /Sverker, Erlang/OTP Ericsson


Diego Llarrull wrote:
> Hello Sverker,
>
> The patch indeed solved the mentioned bug and, since our app evidently 
> made heavy use of this function, it works perfectly right now.
> Thank you very much for the (very) swift response and help.
>
> One final question, will this patch make it to any upcoming Erlang 
> release? That would avoid the need to patch big.c on every deployment 
> machine.
>
> Thanks again,
>
> Diego
>
> On 20/02/12 10:01, Sverker Eriksson wrote:
>> Here is a preliminary source patch:
>>
>> diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c
>> index 976f05c..8848741 100644
>> --- a/erts/emulator/beam/big.c
>> +++ b/erts/emulator/beam/big.c
>> @@ -1867,9 +1867,12 @@ Eterm bytes_to_big(byte *xp, dsize_t xsz, int 
>> xsgn, Eterm *r)
>>        d = 0;
>>        for(i = xsz; --i >= 0;)
>>            d = (d << 8) | xp[i];
>> +       if (++rsz == 1 && IS_USMALL(xsgn,d)) {
>> +           if (xsgn) d = -d;
>> +           return make_small(d);
>> +       }
>>        *rwp = d;
>>        rwp++;
>> -       rsz++;
>>     }
>>     return big_norm(r, rsz, (short) xsgn);
>> }
>>
>>
>> Sverker Eriksson wrote:
>>> Hi Diego,
>>>
>>> Thanks for the exemplary test code to provoke the bug. I get the 
>>> same crash on my 64-bit machine.
>>>
>>> I think I found what it is. To be continued on Monday...
>>>
>>> /Sverker, Erlang/OTP, Ericsson
>>>
>>> Diego Llarrull wrote:
>>>> Hello everyone,
>>>>
>>>> I'm currently developing a distributed store written entirely in 
>>>> Erlang, and we are having a somewhat awkward problem: the app runs 
>>>> fine in 32-bit Erlang VMs but ALWAYS crashes in 64-bit Erlang VMs.
>>>> We've tested 64-bit Erlang VMs running on Linux (XUbuntu 
>>>> 11.04/Fedora 15) 64-bit, OS X Lion 64-bit, and FreeBSD 8.2 64-bit 
>>>> with exactly the same result: a segmentation fault as soon as we 
>>>> try to
>>>> to use the store.
>>>>
>>>> We managed to track down one bug, which was caused by inserting the 
>>>> same record twice, on a compressed, named ETS table with bag 
>>>> implementation. This causes, inexplicably, a segmentation fault which
>>>> is solved my changing the Ets table to a set.
>>>>
>>>>
>>>> To replicate the bug, the following code can be run:
>>>>
>>>>     -module(segviola14).
>>>>     -compile(export_all).
>>>>
>>>>     init() ->
>>>>     S =     {
>>>>                {1316110174588445,1316110174588583},
>>>>                {1316110174588445,1316110174588590}
>>>>     },
>>>>     DB=ets:new(childName, [named_table, bag, compressed]),
>>>>     ets:insert(DB, S), io:format("guau!~n"),
>>>>     ets:insert(DB, S), io:format("guau!~n").
>>>>
>>>>         The output for this code is:
>>>>
>>>>>  segviola14:init().
>>>> guau!
>>>> Segmentation fault (core dumped)
>>>>
>>>>
>>>> In 32-bit Erlang VMs this code works just fine. We are, however, 
>>>> having segmentation faults throught our code that make us think the 
>>>> bug affects a core area of the VM-code. 32-bit Erlang showed
>>>> none of these problems, with everything running fine.
>>>>
>>>> Any ideas?
>>>>
>>>> Thank you all in advance.
>>>>
>>>>
>>>> Diego
>>>>
>>>>
>>>>
>>>>
>>>> ------------------------------------------------------------------------ 
>>>>
>>>>
>>>> _______________________________________________
>>>> erlang-bugs mailing list
>>>> erlang-bugs@REDACTED
>>>> http://erlang.org/mailman/listinfo/erlang-bugs
>>>
>>>
>>> _______________________________________________
>>> erlang-bugs mailing list
>>> erlang-bugs@REDACTED
>>> http://erlang.org/mailman/listinfo/erlang-bugs
>>>
>>
>>
>
>




More information about the erlang-bugs mailing list