Проблема загрузки библиотеки с FFI в PHP 7.4 - PullRequest
2 голосов
/ 29 января 2020

У меня проблемы с использованием сторонней библиотеки .so в PHP с новым FFI. Когда я запускаю этот маленький кусочек кода:

<?php

$ffi = FFI::cdef('typedef int (*NFE_Nome)(const char* sNome, int* esTamanho);', 'libacbrnfe64.so');

PHP выдает мне эту ошибку:

double free or corruption (out)
Aborted (core dumped)

Это проблема с самой библиотекой, моей конфигурацией PHP или что-то другое? Это сбивает с толку, потому что я могу нормально использовать эту же библиотеку с этим кодом C ++:

#include <iostream>
#include <dlfcn.h>

typedef int (*NFE_Nome)(const char* sNome, int* esTamanho);

#define BUFFER_LEN 256

int main() {
    void *lib = dlopen("libacbrnfe64.so", RTLD_LAZY);

    auto libMethod = (NFE_Nome) dlsym(lib, "NFE_Nome");

    const std::string bufferNome(BUFFER_LEN, ' ');
    int bufferNomeLength = BUFFER_LEN;

    libMethod(bufferNome.c_str(), &bufferNomeLength);

    std::cout << bufferNome << std::endl;
    return 0;
}

Я знаю, что код PHP не выполняет функцию NFE_Nome, но я получаю ошибка перед попыткой вызова самой функции.

1 Ответ

1 голос
/ 30 января 2020

- Правка -

Эта проблема является результатом двух ошибок в двух разных программах.

  1. При связывании общих объектов fp c -3.0 .0 (или новее) добавляет это к зависимостям (как первая зависимость): /lib64/ld-linux-x86-64.so.2

  2. ld- linux -x86-64.so.2 export a calloc вариант, который (не всегда) не очищает возвращаемую память (подробности ниже) *) опция fpc), но перед запуском ./ppas.sh исправление link.res файла. Для этого я взломал этот awk-скрипт, но чувствую, что он немного неуклюж /lib64/ld-linux-x86-64.so.2 в зависимые разделяемые библиотеки, что не является ни обязательным, ни полезным.

    Фактически, это привело к версии calloc, которая возвращает ненулевую память. Подробности описаны здесь: https://www.linuxquestions.org/questions/programming-9/debugging-dlopen-4175668676/ и здесь: Почему вызов callo c в gdb не обнуляет память?

    Предлагаемое решение: измените связь в соответствии с примером:

    - gcc -shared -o demodule.so demodule.o /lib64/ld-linux-x86-64.so.2 -lglib-2.0
    + gcc -shared -o demodule.so demodule.o -lglib-2.0
    

    Разницу можно проверить с помощью readelf -d. Неправильно:

    Dynamic section at offset 0x828 contains 26 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [ld-linux-x86-64.so.2]
     0x0000000000000001 (NEEDED)             Shared library: [libglib-2.0.so.0]
     0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
    

    Правый вывод:

    Dynamic section at offset 0x7f8 contains 25 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [libglib-2.0.so.0]
     0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
    

    Кроме того, с помощью команды ldd demodule.so строка, содержащая /lib64/ld-linux-x86-64.so.2, должна быть последней.

    Редактировать: обсуждение на sourceware.org этой проблемы: https://sourceware.org/bugzilla/show_bug.cgi?id=25486

    Редактировать: бесплатно pascal сторона: https://bugs.freepascal.org/view.php?id=36706

...