php / php/php-src

preloading shutdown frees objects before module shutdown

オープン
#9,957 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Bug Extension: opcache Status: Needs Triage
主要言語
C
スター
40.4k
フォーク
8.2k
平均マージ
2日 13時間
マージ済み PR(30日)
96

説明

Description

Since cecea72a10aa6470b3426a8d2f905f5ef2fe29b3, preloading executes zend_shutdown_executor_values() early in accel_preload() directly, causing zend_objects_store_free_object_storage() to be called long before php_request_shutdown() is called, which calls php_module_shutdown() - before zend_shutdown_executor_values, normally.

Can we bring consistency here between regular request shutdown and preloading shutdown, so that the latter needs no special handling?

This change led to a crash in our extension creating an object at rinit and accessing it in rshutdown: https://github.com/DataDog/dd-trace-php/issues/1795

==77== Invalid read of size 8
==77==    at 0x583BB80: ddtrace_close_all_open_spans (span.c:504)
==77==    by 0x582CAAB: zm_deactivate_ddtrace (ddtrace.c:897)
==77==    by 0x582CAAB: zm_deactivate_ddtrace (ddtrace.c:882)
==77==    by 0x51C81B: zend_deactivate_modules (in /usr/local/sbin/php-fpm)
==77==    by 0x4B0FB3: php_request_shutdown (in /usr/local/sbin/php-fpm)
==77==    by 0x56155FF: accel_finish_startup_preload (in /usr/local/lib/php/extensions/no-debug-non-zts-20210902/opcache.so)
==77==    by 0x5810D13: zai_interceptor_post_startup (interceptor.c:683)
==77==    by 0x515397: zend_post_startup (in /usr/local/sbin/php-fpm)
==77==    by 0x4B18DF: php_module_startup (in /usr/local/sbin/php-fpm)
==77==  Address 0x5a63b88 is 184 bytes inside a block of size 272 free'd
==77==    at 0x48C7488: free (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==77==    by 0x5B2B4B: zend_objects_store_del (in /usr/local/sbin/php-fpm)
==77==    by 0x5ADA7F: zend_object_std_dtor (in /usr/local/sbin/php-fpm)
==77==    by 0x5B2A3B: zend_objects_store_free_object_storage (in /usr/local/sbin/php-fpm)
==77==    by 0x504A17: zend_shutdown_executor_values (in /usr/local/sbin/php-fpm)
==77==    by 0x5613F5B: accel_preload (in /usr/local/lib/php/extensions/no-debug-non-zts-20210902/opcache.so)
==77==    by 0x56155CB: accel_finish_startup_preload (in /usr/local/lib/php/extensions/no-debug-non-zts-20210902/opcache.so)
==77==    by 0x5810D13: zai_interceptor_post_startup (interceptor.c:683)
==77==    by 0x515397: zend_post_startup (in /usr/local/sbin/php-fpm)
==77==    by 0x4B18DF: php_module_startup (in /usr/local/sbin/php-fpm)
==77==  Block was alloc'd at
==77==    at 0x48C4EC0: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==77==    by 0x4E6FB3: __zend_malloc (in /usr/local/sbin/php-fpm)
==77==    by 0x4EBA4F: _ecalloc (in /usr/local/sbin/php-fpm)
==77==    by 0x5828C8B: ddtrace_span_data_create (ddtrace.c:404)
==77==    by 0x5181EB: object_init_ex (in /usr/local/sbin/php-fpm)
==77==    by 0x583B063: ddtrace_init_span (span.c:247)
==77==    by 0x583B063: ddtrace_push_root_span (span.c:284)
==77==    by 0x582AA9B: zm_activate_ddtrace (ddtrace.c:834)
==77==    by 0x51C67F: zend_activate_modules (in /usr/local/sbin/php-fpm)
==77==    by 0x4B0BAB: php_request_startup (in /usr/local/sbin/php-fpm)

(ping @nikic being commit author)

PHP Version

PHP 8.1+

Operating System

No response

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

まず accel_preload() と zend_shutdown_executor_values() を追跡し、次にそれらの順序を php_request_shutdown() および php_module_shutdown() と比較します。報告されている PHP 8.1+ の preload シナリオと Valgrind trace を再現の基準として使用してください。preload のシャットダウンで、モジュールのシャットダウンパスが必要とする前にオブジェクトが解放されなくなり、報告されている invalid read が発生しなければ完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
c, php
領域
backend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。