I see this issue on two different physical machines with different Linux flavours (Ubuntu Server 18.4.4 in VM and Slackware 14.2 on bare metal).
I try to make a "closed loop" allowing Threaded tasks to submit new tasks back into the pool via a Volatile queue being polled by the main thread controlling the pool. I hope I did not overengineer this..
Anyways, on both machines this behaves very bad. Before compiling the most visible issue was data missing in mid processing the threaded object:
class MyTask extends Threaded
{
public function __construct(string $name, int $ttl, int $count = 0)
...
public function run() : void
{
echo "+Task " . $x . " running with ttl " . $this->ttl ." and count ". $this->count. "\n";
$child = new MyTask($x, $this->ttl - 1, $this->count + 1);
}
}
Fatal error: Uncaught TypeError: Argument 1 passed to MyTask::__construct() must be of the type string, null given,
After recompiling with --with-pthreads-sanitize AS reports very soon a "heap-use-after-free".
==14934==ERROR: AddressSanitizer: heap-use-after-free on address 0x608000004220 at pc 0x7fd70dc24f0d bp 0x7fd70d1fe940 sp 0x7fd70d1fe930
#0 0x7fd70dc24f0c in pthreads_monitor_check /root/pthreads-master/src/monitor.c:67
#1 0x7fd70dc15653 in pthreads_routine_run_function /root/pthreads-master/src/object.c:455
#2 0x7fd70dc43167 in pthreads_routine /root/pthreads-master/src/object.c:516
#3 0x7fd7140eb6da in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76da)
#4 0x7fd713a5388e in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x12188e)
0x608000004220 is located 0 bytes inside of 96-byte region [0x608000004220,0x608000004280)
freed by thread T1 here:
#0 0x7fd714b9e7b8 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xde7b8)
#1 0x7fd70dc43d68 in pthreads_base_free /root/pthreads-master/src/object.c:353
#2 0x5568e4e03983 in zend_objects_store_del /root/php-7.2.14/Zend/zend_objects_API.c:189
previously allocated by thread T1 here:
#0 0x7fd714b9ed38 in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xded38)
#1 0x7fd70dc24dcb in pthreads_monitor_alloc /root/pthreads-master/src/monitor.c:33
#2 0x7fd70dc41786 in pthreads_base_ctor /root/pthreads-master/src/object.c:311
#3 0x7fd70dc42270 in pthreads_threaded_ctor /root/pthreads-master/src/object.c:166
#4 0x5568e4dc3a7a in _object_and_properties_init /root/php-7.2.14/Zend/zend_API.c:1332
Thread T2 created by T0 here:
#0 0x7fd714af7d2f in __interceptor_pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x37d2f)
#1 0x7fd70dc4369c in pthreads_start /root/pthreads-master/src/object.c:396
#2 0x7fd70dc18793 in zim_Thread_start classes/thread.h:97
#3 0x5568e4daedd5 in zend_call_function /root/php-7.2.14/Zend/zend_execute_API.c:834
#4 0x556800000000 (<unknown module>)
#5 0x625000000000 (<unknown module>)
Thread T1 created by T0 here:
#0 0x7fd714af7d2f in __interceptor_pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x37d2f)
#1 0x7fd70dc4369c in pthreads_start /root/pthreads-master/src/object.c:396
#2 0x7fd70dc18793 in zim_Thread_start classes/thread.h:97
#3 0x5568e4daedd5 in zend_call_function /root/php-7.2.14/Zend/zend_execute_API.c:834
SUMMARY: AddressSanitizer: heap-use-after-free /root/pthreads-master/src/monitor.c:67 in pthreads_monitor_check
Shadow bytes around the buggy address:
0x0c107fff87f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff8800: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x0c107fff8810: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x0c107fff8820: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x0c107fff8830: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c107fff8840: fa fa fa fa[fd]fd fd fd fd fd fd fd fd fd fd fd
0x0c107fff8850: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x0c107fff8860: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x0c107fff8870: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x0c107fff8880: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x0c107fff8890: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed
heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==14934==ABORTING
Two completely different systems report the same.
My test program is attached, Sorry that this is so messy, after each fail I made it more noisy.
Example output is also attached
output.txtthreadtest2.php.txt
Environment
PHP 7.2.14 (cli) (built: Jan 31 2019 21:15:56) ( ZTS ) Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies pthreads Version => 3.2.1dev
Summary
I see this issue on two different physical machines with different Linux flavours (Ubuntu Server 18.4.4 in VM and Slackware 14.2 on bare metal).
I try to make a "closed loop" allowing Threaded tasks to submit new tasks back into the pool via a Volatile queue being polled by the main thread controlling the pool. I hope I did not overengineer this..
Anyways, on both machines this behaves very bad. Before compiling the most visible issue was data missing in mid processing the threaded object:
Fatal error: Uncaught TypeError: Argument 1 passed to MyTask::__construct() must be of the type string, null given,
After recompiling with --with-pthreads-sanitize AS reports very soon a "heap-use-after-free".
Two completely different systems report the same.
My test program is attached, Sorry that this is so messy, after each fail I made it more noisy. Example output is also attached output.txt threadtest2.php.txt