[erlang-bugs] Data passed by port_call is corrupted under smp.
YAMASHINA Hio
hio@REDACTED
Mon Oct 1 12:43:26 CEST 2007
Hi all.
Bif port_call uses pre-allocated buffer,
and reuse it on succeeding call.
But there is no any protection.
Then, when using -smp option and port-locking,
port_call data is overwritten by another thread.
code for reproduction is here:
http://fleur.hio.jp/~hio/prive/port_buffer_corruption.tar.gz
9ed0a6e9d5ac5a1b85d80ab3ba8f3ac8 port_buffer_corruption.tar.gz
Running make test raises an exception.
In call function of this driver,
1. dump data contained in buffer.
>> port[86] (A) 83 a 2 cmd[2] buf=0x2aaaaab248c8 thr=1084270944
(port id, "(A)", data, command, pointer and pthread_t)
2. sleep 1 sec (for ease of reproduction).
3. dump same data again.
>> port[86] (B) 83 a 3 cmd[2] buf=0x2aaaaab248c8 thr=1084270944
4. return incoming data as return value.
At this point, erts_port_call_buff (erts/emulator/beam/erl_bif_port.c)
is shared in a OS-specific process.
I guess it is required something exclusive control or
to make it store as thread-specific.
Attached patch is quick hack workaround for this problem.
This patch is just a quick hack and using pthread
library directly.
Tested on otp_src_R11B-5 and otp_src_R12B-0.
before patched:
$ erl -smp +S 3 -noshell -eval 'my_driver:test_parallel(), halt()'
port[86] (A) 83 a 2 cmd[2] buf=0x2aaaaab248c8 thr=1080068448
port[87] (A) 83 a 3 cmd[3] buf=0x2aaaaab248c8 thr=1082169696
port[85] (A) 83 a 1 cmd[1] buf=0x2aaaaab248c8 thr=1084270944
port[85] (B) 83 a 1 cmd[1] buf=0x2aaaaab248c8 thr=1084270944
port[88] (A) 83 a 4 cmd[4] buf=0x2aaaaab248c8 thr=1084270944
port[86] (B) 83 a 4 cmd[2] buf=0x2aaaaab248c8 thr=1080068448
port[89] (A) 83 a 5 cmd[5] buf=0x2aaaaab248c8 thr=1080068448
port[87] (B) 83 a 5 cmd[3] buf=0x2aaaaab248c8 thr=1082169696
port[88] (B) 83 a 5 cmd[4] buf=0x2aaaaab248c8 thr=1084270944
port[89] (B) 83 a 5 cmd[5] buf=0x2aaaaab248c8 thr=1080068448
child:1 collected
=ERROR REPORT==== 1-Oct-2007::19:29:10 ===
Error in process <0.30.0> with exit value: {{badmatch,{2,4}},[{my_driver,child,4}]}
=ERROR REPORT==== 1-Oct-2007::19:29:11 ===
Error in process <0.31.0> with exit value: {{badmatch,{3,5}},[{my_driver,child,4}]}
=ERROR REPORT==== 1-Oct-2007::19:29:11 ===
Error in process <0.32.0> with exit value: {{badmatch,{4,5}},[{my_driver,child,4}]}
Communication buffer is shared with every threads.
after patched:
$ erl -smp +S 3 -noshell -eval 'my_driver:test_parallel(), halt()'
port[86] (A) 83 a 2 cmd[2] buf=0x2aaaaab24ab0 thr=1082169696
port[87] (A) 83 a 3 cmd[3] buf=0x2aaaaab24be0 thr=1084270944
port[85] (A) 83 a 1 cmd[1] buf=0x2aaaaab24900 thr=1080068448
port[86] (B) 83 a 2 cmd[2] buf=0x2aaaaab24ab0 thr=1082169696
port[88] (A) 83 a 4 cmd[4] buf=0x2aaaaab24ab0 thr=1082169696
port[87] (B) 83 a 3 cmd[3] buf=0x2aaaaab24be0 thr=1084270944
port[89] (A) 83 a 5 cmd[5] buf=0x2aaaaab24be0 thr=1084270944
port[85] (B) 83 a 1 cmd[1] buf=0x2aaaaab24900 thr=1080068448
port[88] (B) 83 a 4 cmd[4] buf=0x2aaaaab24ab0 thr=1082169696
port[89] (B) 83 a 5 cmd[5] buf=0x2aaaaab24be0 thr=1084270944
child:1 collected
child:2 collected
child:3 collected
child:4 collected
child:5 collected
$
Each thread has own buffer.
Regards.
--
YAMASHINA Hio <hio@REDACTED>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: otp_src_R11B-5.portfix.patch
Type: application/octet-stream
Size: 2364 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20071001/fc1d514a/attachment.obj>
More information about the erlang-bugs
mailing list