clang 链接器中的 BUG - 名称解析问题

clang 链接器中的 BUG - 名称解析问题

我在 clang 中发现了错误,并将其发布在这里,因为很难找到如何在 clang 系统中执行此操作。我认为这些信息很有用 - 我在网上看到了类似的问题。

因此,clang 进行了错误的链接。它是 OpenBSD 6.3 amd64,稳定。

当模块之一具有与库函数同名的全局变量时,它将库函数调用链接到变量,即使变量的类型为“int”。例子:

主(简单)模块“socket.cpp”,调用 socket():

#include <stdio.h>
#include <sys/socket.h>

int
main(int argc, char * argv[]){
    int result = socket(AF_INET, SOCK_DGRAM, 17);

    printf("result = %d\n", result);

    return 0;
}

第二个模块“add.cpp”,其全局变量名为“socket”:

int socket = 5;

您可以使用 makefile/clang 进行编译并链接它们,而不会发出警告。但是当您运行该程序时 - 您会收到“分段错误”。

如果我在反汇编程序中看到可执行文件,我会看到 - 没有调用系统函数“socket”。它以丑陋的方式“调用”这个变量。

如果有人知道如何向 clang 社区提交此错误报告,请...

更新1

clang 被如下调用:

clang -o test  socket.o add.o

更新2

嗯,我想这是预料之中的。链接器应该如何区分两个套接字符号? – 箭头

Microsoft编译器如何区分呢?技术难度很大?这段代码在 Visual Studio 中运行良好。那里不是问题。

更新3

然后代码“调用”它,从而导致崩溃。这不是一个错误。 – 箭头

在程序员的逻辑中这是BUG。如何调用变量“int”?这种设计的具体人体工程学效果很差。

为什么链接器没有提到“调用”变量“int”。这是无稽之谈。这是糟糕的系统设计。

必须警告链接过程中的歧义。沉默的行为——错误的春天。

答案1

发生这种情况是因为您试图将整数作为函数执行。int socket = 5;与函数同名有socket() 一种更简单的方法可以实现这一点,如下所示:

$ cat main.c
int main = 9;
$ clang -Wall main.c
$ ./a.out
Segmentation fault

更新:正如@Kusalananda 在评论中提到的那样,它不仅发生在 clang 上。

答案2

链接器将socket符号解析为您的整数变量。然后代码“调用”它,从而导致崩溃。这不是一个错误。

由于使用特殊的修饰方案来装饰所有导出的符号,它恰好可以与 Microsoft 编译器一起使用。在此方案中,C 函数和全局变量的修饰方式不同 ( ?socket@@YAHHHH@Zvs ?socket@@3HA),这导致了不同的符号名称。在 *nix 系统上,普通 C 函数和全局变量不使用重整。

相关内容