为什么 free() 会在其中一个上运行核心转储,而在另一个上运行不?

为什么 free() 会在其中一个上运行核心转储,而在另一个上运行不?

我有这个非常简单的源代码作为测试程序:

#include <stdio.h>
#include <stdlib.h>

int main()
{
        FILE *fp;

        fp = fopen("file.txt", "w");

        fclose(fp);
        fclose(fp);

        printf("Completed successfully\n\n");
        return(0);
}

我在两台 Ubuntu 服务器上运行此代码,两台服务器都运行 Ubuntu 18.04 LTS。它在 MachA 上 fopen 时死机,而在 MachB 上运行良好并显示“已成功完成”。

确切的错误是:

./testpgm
free(): double free detected in tcache 2
Abort(coredump)

使用 gdb,代码似乎使用了相同的搜索路径。两个系统中都报告了相同的共享库:

(gdb) info sharedlibrary
From                To                  Syms Read   Shared Object Library
0x00007ffff7dd3f10  0x00007ffff7df4570  Yes         /lib64/ld-linux-x86-64.so.2
0x00007ffff7a032d0  0x00007ffff7b7bb7c  Yes         /lib/x86_64-linux-gnu/libc.so.6

我能想到的唯一可能影响这一点的是,在问题机器上,我有 g++-9,但我不确定是如何安装它的,因为它似乎不再在 apt-get 中列为可安装包。

问题服务器:

g++-7/bionic-updates,bionic-security,now 7.5.0-3ubuntu1~18.04 amd64 [installed]
g++-8/bionic-updates,bionic-security,now 8.4.0-1ubuntu1~18.04 amd64 [installed]
g++-9/bionic,now 9.3.0-11ubuntu0~18.04.1 amd64 [installed]

工作服务器:

g++-8/bionic-updates,bionic-security,now 8.4.0-1ubuntu1~18.04 amd64 [installed]

是否有可能 apt 中提供了 g++-9 供下载,但后来由于出现问题而被删除?我正在考虑尝试删除该软件包,看看是否能解决问题,但想知道是否有其他人遇到过这个问题,或者对其他需要查找的内容有什么建议。

更新:

根据 waltinator 的建议,我尝试了 strace 命令,但它并没有提供太多关于为什么会发生这种情况的见解。strace 在工作系统和问题系统之间显示的数据几乎相同。唯一的区别是一开始尝试访问正在工作的副本上的 ld.so.preload。

当它真正失败时,我仍然不明白为什么。

工作系统

openat(AT_FDCWD, "file.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
write(1, "Completed successfully\n", 23Completed successfully
) = 23
write(1, "\n", 1
)                       = 1

失败的系统

brk(NULL)                               = 0x5559121ec000
brk(0x55591220d000)                     = 0x55591220d000
openat(AT_FDCWD, "file.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(3)                                = 0
writev(2, [{iov_base="free(): double free detected in "..., iov_len=40}, {iov_base="\n", iov_len=1}], 2free(): double free detected in tcache 2
) = 41
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7faddf948000
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0

ulimit 值的不同仅仅是因为在故障系统上内存量为 64GB,而在工作系统上内存量为 128GB。我想也许是内存不足,但我可以运行其他程序,例如启动 Postgres 并访问数据库。

相关内容