Apparent race condition in dets can corrupt the file
John Hughes
john.hughes@REDACTED
Thu Sep 23 23:22:48 CEST 2010
It looks as though QuickCheck has turned up another race condition in dets,
this one involving three processes. The minimal example is:
...ensure that the file dets_table does not exist...
dets:open_file(dets_table,[{type,bag}]),
dets:close(dets_table),
dets:open_file(dets_table,[{type,bag}]),
In parallel:
dets:lookup(dets_table,0)
dets:insert(dets_table,{0,0})
dets:insert(dets_table,{0,0})
dets:match_object(dets_table,'_')
All calls return the correct results until the call to match_object, which
returns {error,{premature_eof,"dets_table"}}.
This looks as though it could be the same bug Tobbe Törnqvist mentioned
here:
http://www.erlang.org/cgi-bin/ezmlm-cgi?4:msp:29771
"We know there is a lurking bug somewhere in the dets code. We have got 'bad
object' and 'premature eof' every other month the last year. We have not
been able to track the bug down since the dets files is repaired
automatically next time it is opened."
In this case too, the file is left in a state that causes it to be repaired
when it is reopened. After the repair, though, the data inserted into the
table has been lost.
Caveats:
* The race condition occurs only rarely--I need to repeat the test case up
to hundreds of times to hit it. This repetition may perhaps be necessary to
provoke the failure.
* I'm using Windows... antivirus programs or even the file system itself
might be involved.
* I can only provoke the bug using QuickCheck--coding up the dets calls in a
simple Erlang function does not seem to provoke it. I speculate that this is
because QuickCheck makes the calls a little more slowly... it's interpreting
the test case after all... so the timing is different, and that may affect
the likelihood of hitting the race. Of course, QuickCheck is not calling
dets internally.
I'm attaching a copy of my test code, which tries the test up to 1000 times
and, on my laptop, provokes the error virtually every time. You run it like
this:
Erlang R14B (erts-5.8.1) [smp:2:2] [rq:2] [async-threads:0]
Eshell V5.8.1 (abort with ^G)
1> dets_eqc:bug().
Failed! Reason:
{'EXIT',{badarg,[{erlang,length,[{error,{premature_eof,"dets_table"}}]},
{dets_eqc,corrupted,2},
{dets_eqc,'-prop_parallel/0-fun-2-',3},
{eqc_gen,'-f388_0/1-fun-0-',3},
{eqc_gen,gen,3},
{eqc,'-f880_0/1-fun-2-',3},
{eqc_gen,'-f330_0/2-fun-1-',4},
{eqc_gen,f274_0,3}]}}
bag
1000
{[{init,{init_state,{state,undefined,bag,[],0}}},
{set,{var,15},{call,dets_eqc,open_file,[dets_table,[{type,bag}]]}},
{set,{var,20},{call,dets,close,[dets_table]}},
{set,{var,21},{call,dets_eqc,open_file,[dets_table,[{type,bag}]]}}],
[[{set,{var,22},{call,dets,lookup,[dets_table,0]}}],
[{set,{var,24},{call,dets,insert,[dets_table,{0,0}]}}],
[{set,{var,25},{call,dets,insert,[dets_table,{0,0}]}}]]}
History:
[{{set,{var,15},{call,dets_eqc,open_file,[dets_table,[{type,bag}]]}},
dets_table},
{{set,{var,20},{call,dets,close,[dets_table]}},ok},
{{set,{var,21},{call,dets_eqc,open_file,[dets_table,[{type,bag}]]}},
dets_table}]
Parallel: [[{set,{var,22},{call,dets,lookup,[dets_table,0]},[]}],
[{set,{var,24},{call,dets,insert,[dets_table,{0,0}]},ok}],
[{set,{var,25},{call,dets,insert,[dets_table,{0,0}]},ok}]]
Res: ok
false
2>
I'm also attaching a copy of the dets file, just after the test has ended,
in case that helps. I'm using QuickCheck version 1.22 to run the test, which
can be downloaded from http://quviq-licencer.com/downloads/eqc-1.22.zip.
(Note that earlier versions of QuickCheck can't run this example--it makes
use of very recent additions). No licence is needed to run the bug()
function above.
I'm running on an Intel L9400 (Core2Duo). Be interesting to know whether
this example fails on other architectures and under other operating systems.
John
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dets_eqc.erl
Type: application/octet-stream
Size: 7964 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20100923/18945396/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dets_table
Type: application/octet-stream
Size: 5432 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20100923/18945396/attachment-0001.obj>
More information about the erlang-bugs
mailing list