[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