简体   繁体   English

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

[英]Problem loading a library with FFI in PHP 7.4

I'm having trouble using a third party .so library in PHP with the new FFI.我在新的 FFI 中使用 PHP 中的第三方 .so 库时遇到问题。 When I run this little piece of code:当我运行这段代码时:

<?php

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

PHP outputs me this error: PHP 输出我这个错误:

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

Is this a problem with the library itself, my PHP configuration or something else?这是库本身的问题,我的PHP配置还是其他问题? It's confusing to me, because I can use normally this same library with this C++ code:这让我感到困惑,因为我通常可以在这个 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;
}

I'm aware that the PHP code doesn't execute the NFE_Nome function, but I'm getting the error before trying to call the function itself.我知道 PHP 代码不执行 NFE_Nome 函数,但是在尝试调用函数本身之前我收到了错误。

-- Edit -- - 编辑 -

This problem is result of two bugs in two different programs.这个问题是两个不同程序中的两个错误的结果。

  1. When linking a shared objects, fpc-3.0.0 (or newer) adds this to the dependencies (as the first dependency): /lib64/ld-linux-x86-64.so.2链接共享对象时,fpc-3.0.0(或更新版本)将其添加到依赖项(作为第一个依赖项):/ /lib64/ld-linux-x86-64.so.2

  2. ld-linux-x86-64.so.2 exports a calloc variant, that doesn't (always) clears the memory it returns (details below) ld-linux-x86-64.so.2 导出一个calloc变体,它不会(总是)清除它返回的内存(详情如下)

The workaround OP suggested is linking in a separate pass (using -E (or -Cn ) option of fpc ), but before running ./ppas.sh fixing link.res file. OP 建议的解决方法是在单独的通道中进行链接(使用fpc -E (或-Cn )选项),但在运行./ppas.sh修复link.res文件之前。 For that, I hacked this awk-script, but I do feel it a bit clumsy:为此,我破解了这个 awk 脚本,但我确实觉得它有点笨拙:

#!/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; }

-- Original answer -- ——原答案——

Sounds like a linking problem: you might have added /lib64/ld-linux-x86-64.so.2 into the dependent shared libraries, which is neither required or useful.听起来像是链接问题:您可能已将/lib64/ld-linux-x86-64.so.2添加到依赖共享库中,这既不需要也没有用。

Actually, it resulted a calloc version that returns non-zeroed memory.实际上,它导致了一个返回非零内存的calloc版本。 The details are described here: https://www.linuxquestions.org/questions/programming-9/debugging-dlopen-4175668676/ and here: Why does calling calloc in gdb not appear to zero out the memory?详细信息在此处描述: https : //www.linuxquestions.org/questions/programming-9/debugging-dlopen-4175668676/和此处: 为什么在 gdb 中调用 calloc 似乎不会将内存清零?

Suggested solution: change the linkage according to the example:建议的解决方案:根据示例更改联动:

- 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

The difference can be checked with readelf -d .可以使用readelf -d检查差异。 Wrong:错误的:

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]

Right output:右输出:

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]

Also, with command ldd demodule.so the line containing /lib64/ld-linux-x86-64.so.2 should be the last one.此外,与命令ldd demodule.so包含线路/lib64/ld-linux-x86-64.so.2应该是最后一个。

Edit: discussion on sourceware.org regarding this problem: https://sourceware.org/bugzilla/show_bug.cgi?id=25486编辑:关于这个问题的关于 sourceware.org 的讨论: https ://sourceware.org/bugzilla/show_bug.cgi?id = 25486

Edit: on Freepascal side: https://bugs.freepascal.org/view.php?id=36706编辑:在 Freepascal 方面: https ://bugs.freepascal.org/view.php ? id = 36706

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM