Ошибка сегмента в расширении после вызова функции PHP из 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).

Любая идея, как преодолеть ошибку Seg?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
103
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно разместить возвращаемое значение 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 где-либо в вызове (поскольку возвращаемое значение не имеет имени в пользовательском пространстве).

Другие вопросы по теме