セグメンテーションを起動しないでスレッド内のメモリをemallocできないのはhttps://github.com/php/php-src/blob/master/Zend/zend_alloc.c#L2409です。PHP拡張モジュールのスレッドからemallocを使用しているときのSegfault
スレッドセーフバージョンのPHP(ZTS)で実行している場合のみ、segfaultが発生します(皮肉なことに)。
プレーンなNTSビルドで実行すると、すべて正常に動作します。
問題を再現するために使用できるコードがいくつかあります(私は拡張機能の作成を簡単にするためにphp-cppを使用しています)。
void* test(void* wrapper){
emalloc(sizeof(Php::Value));
return NULL;
}
void VoIP::__construct()
{
pthread_t a;
pthread_create(&a, NULL, test, this);
}
extern "C" {
PHPCPP_EXPORT void *get_module()
{
static Php::Extension extension("php-libtgvoip", "1.0");
Php::Class<VoIP> voip("VoIP");
voip.method<&VoIP::__construct>("__construct", Php::Public | Php::Final);
Php::Namespace danog("danog");
Php::Namespace MadelineProto("MadelineProto");
MadelineProto.add(std::move(voip));
danog.add(std::move(MadelineProto));
extension.add(std::move(danog));
return extension;
}
}
ヘッダ:
#include <php.h>
#include <php_ini.h>
#include <ext/standard/info.h>
#include <phpcpp.h>
class VoIP : public Php::Base {
public:
void __construct();
}
のインスタンス化\ danog \ MadelineProtoのVoIPクラスは、試験中におけるemallocによって引き起こさセグメンテーション違反、()スロー:\
Thread 2 "php" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe91ff700 (LWP 4267)]
0x0000555555cfc7ed in _emalloc (size=32, __zend_filename=0x7fffed9c88a8 "main.cpp", __zend_lineno=30, __zend_orig_filename=0x0, __zend_orig_lineno=0)
at /root/php-src/Zend/zend_alloc.c:2409
2409 if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) {
(gdb) backtrace
#0 0x0000555555cfc7ed in _emalloc (size=32, __zend_filename=0x7fffed9c88a8 "main.cpp", __zend_lineno=30, __zend_orig_filename=0x0, __zend_orig_lineno=0)
at /root/php-src/Zend/zend_alloc.c:2409
#1 0x00007fffed94e80e in test (wrapper=0x555556a73310) at main.cpp:30
#2 0x00007ffff572a494 in start_thread (arg=0x7fffe91ff700) at pthread_create.c:333
#3 0x00007ffff206eaff in clone() at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97
(gdb)
完全なソースコードを見つけることができます@https://github.com/danog/php-libtgvoip
ありがとうございました!しかし、私はどのように正確にスレッドをphpスレッドとして登録することができますかを知りたいのです。単にtsrm_startupを呼び出すだけではうまくいかないようです。 – Danogentili
@Danogentiliあなたは単純にそうしません。私はあなたが自分のスレッドをPHPスレッドとして初期化しても、PHPスレッドを元のスレッドに渡すことはできないと考えています。また、PHPオブジェクトを使用し、実際のPHPスレッドの外でPHP関数を呼び出すことは、おそらく悪い考えです。なぜあなたはこれをやりますか? PHPの拡張を書くときは、できるだけ言語の枠を越えることをお勧めします。 – VTT
整数をパラメータとして渡しながら、特定のPHPコールバックを呼び出す必要があります。私は何とかphp pthreads拡張(https://github.com/krakjoe/pthreads)のコードを使用して考えていましたが、スレッドをどのように管理するのかまだ分かりません。 – Danogentili