在 PHP 7.4 中使用 FFI 加载库时出现问题



我在PHP中使用第三方.so库和新的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. 链接共享对象时,fpc-3.0.0(或更高版本(会将其添加到依赖项中(作为第一个依赖项(:/lib64/ld-linux-x86-64.so.2

  2. ld-linux-x86-64.so.2 导出一个calloc变体,它不会(总是(清除它返回的内存(详细信息如下(

OP 建议的解决方法是在运行修复文件之前-E单独的传递(使用fpc的 (或-Cn(选项(链接link.res./ppas.sh但。为此,我破解了这个尴尬的脚本,但我确实觉得它有点笨拙:

#!/usr/bin/awk -f
$0=="INPUT(" { state=1; next; }
$0=="/lib64/ld-linux-x86-64.so.2" { state=2; next; }
$0==")" && state>0 { state=0;next; }
state==1 { print "INPUT("; state=0; }
{ print $0; }

--原答案 --

听起来像是一个链接问题:您可能已将/lib64/ld-linux-x86-64.so.2添加到依赖的共享库中,这既不是必需的,也不是有用的。

实际上,它产生了一个返回非零内存的calloc版本。详细信息描述如下:https://www.linuxquestions.org/questions/programming-9/debugging-dlopen-4175668676/和此处:为什么在 gdb 中调用 calloc 似乎不会将内存归零?

建议解决方案:根据示例更改联动:

- 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

编辑:在Freepascal一侧:https://bugs.freepascal.org/view.php?id=36706

最新更新