簡體   English   中英

從C調用PHP函數后,擴展段出現段錯誤

[英]Seg fault in extension after calling PHP function from C

我正在嘗試編寫一個擴展,可以在完成工作后回調PHP函數。 為了檢查可行性,我按照這篇文章進行操作: https : //devzone.zend.com/303/extension-writing-part-i-introduction-to-php-and-zend/

基本擴展正常。 然后,我添加了如下代碼來調用PHP函數:

PHP_FUNCTION(hello_world)
{
    zval p1;
    INIT_ZVAL(p1);
    ZVAL_STRING(&p1, "From extension", 1);
    zval *params = { &p1 };
    zend_uint param_count = 1;
    zval *retval_ptr = NULL;

    zval function_name;
    INIT_ZVAL(function_name);
    ZVAL_STRING(&function_name, "from_ext", 1);

    if (call_user_function(
            CG(function_table), NULL /* no object */, &function_name,
            retval_ptr, param_count, &params TSRMLS_CC
        ) == SUCCESS
    ) {
        printf("Success returning from PHP");
        if (retval_ptr)
          zval_ptr_dtor(&retval_ptr);
    }

    /* don't forget to free the zvals */
    zval_dtor(&function_name);
    zval_dtor(&p1);

    RETURN_STRING("Hello World", 1);
}

和調用PHP:

<?
function from_ext($arg) {
  echo "In PHP:", $arg;
  return "hello";
}

echo hello_world();

?>

它確實調用了PHP函數並可以看到該值,但此后引發了Seg錯誤:

php -dextension=modules/hello.so test.php
In PHP:From extensionSegmentation fault: 11

我正在MacOS 10.12.6上嘗試使用附帶的PHP(5.6.30)。

任何想法如何克服段錯誤?

您需要在堆棧上分配返回值zval 傳遞給call_user_function的指針必須為非NULL。 這是一個應解決此問題的補丁。

--- a/mnt/tmpdisk/a.c
+++ b/mnt/tmpdisk/b.c
@@ -5,7 +5,7 @@ PHP_FUNCTION(hello_world)
     ZVAL_STRING(&p1, "From extension", 1);
     zval *params = { &p1 };
     zend_uint param_count = 1;
-    zval *retval_ptr = NULL;
+    zval retval;

     zval function_name;
     INIT_ZVAL(function_name);
@@ -13,12 +13,11 @@ PHP_FUNCTION(hello_world)

     if (call_user_function(
             CG(function_table), NULL /* no object */, &function_name,
-            retval_ptr, param_count, &params TSRMLS_CC
+            &retval, param_count, &params TSRMLS_CC
         ) == SUCCESS
     ) {
         printf("Success returning from PHP");
-        if (retval_ptr)
-          zval_ptr_dtor(&retval_ptr);
+        zval_dtor(&retval);
     }

     /* don't forget to free the zvals */

傳遞指向堆棧分配的內存的指針非常好,因為PHP引擎永遠不會在調用的任何地方捕獲對返回值zval的引用(因為返回值在用戶空間中未命名)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM