Bug #74878 [Opn->Ana]: Data race in ZTS builds

From: Date: Fri, 07 Jul 2017 20:24:44 +0000
Subject: Bug #74878 [Opn->Ana]: Data race in ZTS builds
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-209910@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=74878&edit=1 ID: 74878 Updated by: nikic@php.net Reported by: maroszek at gmx dot net Summary: Data race in ZTS builds -Status: Open +Status: Analyzed Type: Bug Package: *General Issues Operating System: Linux/MacOS PHP Version: 7.2.0alpha3 Block user comment: N Private report: N New Comment: The problem is that https://github.com/php/php-src/blob/master/Zend/zend_API.c#L3758 uses the original name instead of the interned property_info->name. Previous Comments: ------------------------------------------------------------------------ [2017-07-07 20:11:29] maroszek at gmx dot net Description: ------------ Build PHP with thread sanitizer: CFLAGS="-O1 -g -fsanitize=thread" ./configure --disable-fpm --disable-cgi --disable-cli --disable-phpdbg --enable-embed=static --enable-maintainer-zts --without-iconv --enable-json --enable-mbstring Use my ZTS Embed example which produces a lot of parallel executed scripts. https://gist.github.com/paresy/3cbd4c6a469511ac7479aa0e7c42fea7 Build it: clang++ crash.cpp -Imain -ITSRM -IZend -I. --std=c++11 -Llibs -lphp7 -lxml2 -lresolv -ldl -pthread -fsanitize=thread -g -O1 Run it: ./a.out Background: I am trying to locate random segfaults in PHP 7.2 since two weeks... and this is the best i could find yet... (It is a lot better since 7.2! Thanks a lot!) Valgrind shows nothing... And this only shows data races... but i cannot reproduce a crash :( Anyway... It should be fixed nevertheless. Hopefully the data is useful :) Hint: Sometimes the data race happens in zend_destroy_hash. See second log from the output. Test script: --------------- <? class JSONRPCException extends Exception { // } class JSONRPC { private $url; private $username; private $password; function __construct($url) { $data = @parse_url($url); if(($data === false) || !isset($data['scheme']) || !isset($data['host'])) throw new Exception("Invalid URL"); $this->url = $data['scheme']."://".$data['host']; if(isset($data['port'])) $this->url .= ":".$data['port']; if(isset($data['path'])) $this->url .= $data['path']; if(isset($data['user'])) $this->username = $data['user']; else $this->username = ""; if(isset($data['pass'])) $this->password = $data['pass']; else $this->password = ""; } public function __call($method, $arguments) { return self::makeRequest($this->url, $this->username, $this->password, $method, $arguments, false); } static public function __callStatic($method, $params) { return self::makeRequest("http://127.0.0.1:3777/api/", "", "", $method, $params, true); } static private function makeRequest($url, $username, $password, $method, $params, $customErrorHandler) { try { if (!is_scalar($method)) { throw new Exception('Method name has no scalar value'); } if (!is_array($params)) { throw new Exception('Params must be given as array'); } $id = round(fmod(microtime(true)*1000, 10000)); $params = array_values($params); $strencode = function(&$item, $key) { if ( is_string($item) ) $item = utf8_encode($item); else if ( is_array($item) ) array_walk_recursive($item, $strencode); }; array_walk_recursive($params, $strencode); $request = Array( "jsonrpc" => "2.0", "method" => $method, "params" => $params, "id" => $id ); $request = json_encode($request); $header = "Content-type: application/json"."\r\n"; if(($username != "") || ($password != "")) { $header .= "Authorization: Basic ".base64_encode($username.":".$password)."\r\n"; } $options = Array( "http" => array ( "method" => 'POST', "header" => $header, "content" => $request ) ); $context = stream_context_create($options); $response = file_get_contents($url, false, $context); if($response === false) { throw new Exception('Unable to connect'); } if((strpos($http_response_header[0], "200") === false)) { throw new Exception('Server did not respond successfully'); } $response = json_decode($response, true); if (is_null($response)) { throw new Exception('Request error: No response'); } $strdecode = function(&$item, $key) { if ( is_string($item) ) $item = utf8_decode($item); else if ( is_array($item) ) array_walk_recursive($item, $strdecode); }; array_walk_recursive($response, $strdecode); if (isset($response['error'])) { throw new JSONRPCException($response['error']['message']); } if (!isset($response['id'])) { throw new Exception('No response id'); } elseif ($response['id'] != $id) { throw new Exception('Incorrect response id (request id: ' . $id . ', response id: ' . $response['id'] . ')'); } return $response['result']; } catch (Exception $e) { if($customErrorHandler) { set_error_handler(array('JSONRPC', '__errorHandler')); $trace = $e->getTrace(); trigger_error($e->getMessage().' in '.$trace[3]['file'].' on line '.$trace[3]['line'], E_USER_WARNING); restore_error_handler(); return false; } else { throw $e; } } } static private function __errorHandler($errno, $errstr, $errfile, $errline) { if (!(error_reporting() & $errno)) { return; } echo $errstr; return true; } } ?> Expected result: ---------------- No output. Actual result: -------------- ================== WARNING: ThreadSanitizer: data race (pid=25837) Write of size 4 at 0x7d0800009560 by thread T2: #0 do_inherit_property zend_inheritance.c:709 (a.out+0x000100556bb4) #1 zend_do_inheritance zend_inheritance.c:925 (a.out+0x0001005565b1) #2 do_bind_inherited_class zend_compile.c:1183 (a.out+0x0001004a7bcd) #3 zend_do_early_binding zend_compile.c:1240 (a.out+0x0001004a8279) #4 zend_compile_top_stmt zend_compile.c:8080 (a.out+0x0001004bf1d1) #5 zend_compile_top_stmt zend_compile.c:8068 (a.out+0x0001004bf116) #6 zend_compile zend_language_scanner.l:601 (a.out+0x000100468c77) #7 compile_file zend_language_scanner.l:635 (a.out+0x0001004688bf) #8 phar_compile_file phar.c:3320 (a.out+0x0001002d76d5) #9 zend_execute_scripts zend.c:1484 (a.out+0x0001004eb4c9) #10 php_execute_script main.c:2550 (a.out+0x00010042c815) #11 main::$_0::operator()() const crash.cpp:35 (a.out+0x000100001ae3) #12 void* std::__1::__thread_proxy<std::__1::tuple<main::$_0> >(void*) thread:357 (a.out+0x0001000019c2) Previous write of size 4 at 0x7d0800009560 by thread T1: #0 do_inherit_property zend_inheritance.c:709 (a.out+0x000100556bb4) #1 zend_do_inheritance zend_inheritance.c:925 (a.out+0x0001005565b1) #2 do_bind_inherited_class zend_compile.c:1183 (a.out+0x0001004a7bcd) #3 zend_do_early_binding zend_compile.c:1240 (a.out+0x0001004a8279) #4 zend_compile_top_stmt zend_compile.c:8080 (a.out+0x0001004bf1d1) #5 zend_compile_top_stmt zend_compile.c:8068 (a.out+0x0001004bf116) #6 zend_compile zend_language_scanner.l:601 (a.out+0x000100468c77) #7 compile_file zend_language_scanner.l:635 (a.out+0x0001004688bf) #8 phar_compile_file phar.c:3320 (a.out+0x0001002d76d5) #9 zend_execute_scripts zend.c:1484 (a.out+0x0001004eb4c9) #10 php_execute_script main.c:2550 (a.out+0x00010042c815) #11 main::$_0::operator()() const crash.cpp:35 (a.out+0x000100001ae3) #12 void* std::__1::__thread_proxy<std::__1::tuple<main::$_0> >(void*) thread:357 (a.out+0x0001000019c2) Location is heap block of size 32 at 0x7d0800009560 allocated by main thread: #0 malloc <null>:144 (libclang_rt.tsan_osx_dynamic.dylib+0x00000004188a) #1 __zend_malloc zend_alloc.c:2811 (a.out+0x0001004a213a) #2 zend_declare_property zend_API.c:3766 (a.out+0x0001004fa0fe) #3 zend_declare_property_string zend_API.c:3814 (a.out+0x0001004fa47a) #4 zend_register_default_exception zend_exceptions.c:820 (a.out+0x00010052866c) #5 zend_register_default_classes zend_default_classes.c:34 (a.out+0x0001005558f6) #6 zm_startup_core zend_builtin_functions.c:302 (a.out+0x000100513bf1) #7 zend_startup_module_ex zend_API.c:1873 (a.out+0x0001004f39e6) #8 zend_startup_module_zval zend_API.c:1888 (a.out+0x0001004f41e1) #9 zend_hash_apply zend_hash.c:1506 (a.out+0x00010050dda6) #10 zend_startup_modules zend_API.c:1999 (a.out+0x0001004f4007) #11 php_module_startup main.c:2269 (a.out+0x000100429f94) #12 php_embed_startup php_embed.c:109 (a.out+0x0001006385f1) #13 php_embed_init php_embed.c:200 (a.out+0x0001006388d2) #14 main crash.cpp:10 (a.out+0x000100001209) Thread T2 (tid=2628148, running) created by main thread at: #0 pthread_create <null>:144 (libclang_rt.tsan_osx_dynamic.dylib+0x000000024410) #1 std::__1::thread::thread<main::$_0, void>(main::$_0&&) thread:369 (a.out+0x000100001936) #2 std::__1::thread::thread<main::$_0, void>(main::$_0&&) thread:365 (a.out+0x0001000018f0) #3 std::__1::shared_ptr<std::__1::thread> std::__1::shared_ptr<std::__1::thread>::make_shared<main::$_0>(main::$_0&&) memory:3800 (a.out+0x0001000017b1) #4 main crash.cpp:14 (a.out+0x00010000137a) Thread T1 (tid=2628147, running) created by main thread at: #0 pthread_create <null>:144 (libclang_rt.tsan_osx_dynamic.dylib+0x000000024410) #1 std::__1::thread::thread<main::$_0, void>(main::$_0&&) thread:369 (a.out+0x000100001936) #2 std::__1::thread::thread<main::$_0, void>(main::$_0&&) thread:365 (a.out+0x0001000018f0) #3 std::__1::shared_ptr<std::__1::thread> std::__1::shared_ptr<std::__1::thread>::make_shared<main::$_0>(main::$_0&&) memory:3800 (a.out+0x0001000017b1) #4 main crash.cpp:14 (a.out+0x00010000137a) SUMMARY: ThreadSanitizer: data race zend_inheritance.c:709 in do_inherit_property WARNING: ThreadSanitizer: data race (pid=50889) Write of size 4 at 0x7d0800009560 by thread T1: #0 zend_hash_destroy zend_hash.c:1268 (a.out+0x00010050cbcc) #1 destroy_zend_class zend_opcode.c:309 (a.out+0x0001004d40a6) #2 zend_hash_reverse_apply zend_hash.c:997 (a.out+0x00010050f926) #3 shutdown_executor zend_execute_API.c:375 (a.out+0x0001004ca8dc) #4 zend_deactivate zend.c:1060 (a.out+0x0001004e9ac6) #5 php_request_shutdown main.c:1879 (a.out+0x000100428dc1) #6 main::$_0::operator()() const crash.cpp:31 (a.out+0x0001000016ef) #7 void* std::__1::__thread_proxy<std::__1::tuple<main::$_0> >(void*) thread:357 (a.out+0x0001000015c2) Previous write of size 4 at 0x7d0800009560 by thread T3: #0 do_inherit_property zend_inheritance.c:709 (a.out+0x0001005575d4) #1 zend_do_inheritance zend_inheritance.c:925 (a.out+0x000100556fd1) #2 do_bind_inherited_class zend_compile.c:1181 (a.out+0x0001004a79fd) #3 zend_do_early_binding zend_compile.c:1238 (a.out+0x0001004a80a9) #4 zend_compile_top_stmt zend_compile.c:8073 (a.out+0x0001004befa1) #5 zend_compile_top_stmt zend_compile.c:8061 (a.out+0x0001004beee6) #6 zend_compile zend_language_scanner.l:601 (a.out+0x000100468aa7) #7 compile_file zend_language_scanner.l:635 (a.out+0x0001004686ef) #8 phar_compile_file phar.c:3320 (a.out+0x0001002d7715) #9 zend_execute_scripts zend.c:1531 (a.out+0x0001004eba39) #10 php_execute_script main.c:2548 (a.out+0x00010042c715) #11 main::$_0::operator()() const crash.cpp:35 (a.out+0x0001000016e3) #12 void* std::__1::__thread_proxy<std::__1::tuple<main::$_0> >(void*) thread:357 (a.out+0x0001000015c2) Location is heap block of size 32 at 0x7d0800009560 allocated by main thread: #0 malloc <null>:144 (libclang_rt.tsan_osx_dynamic.dylib+0x00000004188a) #1 __zend_malloc zend_alloc.c:2811 (a.out+0x0001004a1f6a) #2 zend_declare_property zend_API.c:3746 (a.out+0x0001004fc30e) #3 zend_declare_property_string zend_API.c:3794 (a.out+0x0001004fc68a) #4 zend_register_default_exception zend_exceptions.c:820 (a.out+0x000100528d1c) #5 zend_register_default_classes zend_default_classes.c:34 (a.out+0x000100556316) #6 zm_startup_core zend_builtin_functions.c:302 (a.out+0x000100514301) #7 zend_startup_module_ex zend_API.c:1873 (a.out+0x0001004f3f56) #8 zend_startup_module_zval zend_API.c:1888 (a.out+0x0001004f4751) #9 zend_hash_apply zend_hash.c:1507 (a.out+0x00010050e4b6) #10 zend_startup_modules zend_API.c:1999 (a.out+0x0001004f4577) #11 php_module_startup main.c:2269 (a.out+0x000100429e94) #12 php_embed_startup php_embed.c:109 (a.out+0x0001006396b1) #13 php_embed_init php_embed.c:200 (a.out+0x000100639992) #14 main crash.cpp:10 (a.out+0x000100000e09) Thread T1 (tid=2489677, running) created by main thread at: #0 pthread_create <null>:144 (libclang_rt.tsan_osx_dynamic.dylib+0x000000024410) #1 std::__1::thread::thread<main::$_0, void>(main::$_0&&) thread:369 (a.out+0x000100001536) #2 std::__1::thread::thread<main::$_0, void>(main::$_0&&) thread:365 (a.out+0x0001000014f0) #3 std::__1::shared_ptr<std::__1::thread> std::__1::shared_ptr<std::__1::thread>::make_shared<main::$_0>(main::$_0&&) memory:3800 (a.out+0x0001000013b1) #4 main crash.cpp:14 (a.out+0x000100000f7a) Thread T3 (tid=2489679, running) created by main thread at: #0 pthread_create <null>:144 (libclang_rt.tsan_osx_dynamic.dylib+0x000000024410) #1 std::__1::thread::thread<main::$_0, void>(main::$_0&&) thread:369 (a.out+0x000100001536) #2 std::__1::thread::thread<main::$_0, void>(main::$_0&&) thread:365 (a.out+0x0001000014f0) #3 std::__1::shared_ptr<std::__1::thread> std::__1::shared_ptr<std::__1::thread>::make_shared<main::$_0>(main::$_0&&) memory:3800 (a.out+0x0001000013b1) #4 main crash.cpp:14 (a.out+0x000100000f7a) SUMMARY: ThreadSanitizer: data race zend_hash.c:1268 in zend_hash_destroy ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=74878&edit=1

« previous php.bugs (#209910) next »