在PHP 7.4中使用FFI加载库时出现问题 [英] Problem loading a library with FFI in PHP 7.4

查看:277
本文介绍了在PHP 7.4中使用FFI加载库时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法在PHP和新的FFI中使用第三方.so库. 当我运行这段代码时:

I'm having trouble using a third party .so library in PHP with the new FFI. When I run this little piece of code:

<?php

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

PHP向我输出此错误:

PHP outputs me this error:

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

这是库本身,我的PHP配置或其他问题吗?这让我感到困惑,因为我通常可以将此同一个库与此C ++代码一起使用:

Is this a problem with the library itself, my PHP configuration or something else? It's confusing to me, because I can use normally this same library with this C++ code:

#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函数,但是在尝试调用函数本身之前遇到了错误.

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.

推荐答案

-编辑-

此问题是两个不同程序中的两个错误导致的.

This problem is result of two bugs in two different programs.

  1. 链接共享对象时,fpc-3.0.0(或更高版本)将其添加到依赖项中(作为第一个依赖项):/lib64/ld-linux-x86-64.so.2

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

ld-linux-x86-64.so.2 exports a calloc variant, that doesn't (always) clears the memory it returns (details below)

建议的解决方法OP是在单独的过程中链接(使用fpc-E(或-Cn)选项),但是在运行./ppas.sh修复link.res文件之前.为此,我修改了这个awk脚本,但确实感到有些笨拙:

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. For that, I hacked this awk-script, but I do feel it a bit clumsy:

#!/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添加到了相关的共享库中,这既不是必需的,也不是有用的.

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.

实际上,它产生了一个calloc版本,该版本返回未归零的内存.此处描述了详细信息: https://www.linuxquestions.org /questions/programming-9/debugging-dlopen-4175668676/和此处:

Actually, it resulted a calloc version that returns non-zeroed memory. 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?

建议的解决方案:根据示例更改链接:

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

可以使用readelf -d检查差异.错误:

The difference can be checked with 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]

右输出:

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的行应为最后一行.

Also, with command ldd demodule.so the line containing /lib64/ld-linux-x86-64.so.2 should be the last one.

关于此问题在sourceware.org上进行的讨论: https://sourceware.org/bugzilla/show_bug.cgi?id=25486

discussion on sourceware.org regarding this problem: https://sourceware.org/bugzilla/show_bug.cgi?id=25486

在Freepascal方面: https://bugs.freepascal.org/view .php?id = 36706

on Freepascal side: https://bugs.freepascal.org/view.php?id=36706

这篇关于在PHP 7.4中使用FFI加载库时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆