为啥 C 程序会在运行时针对 C++ 库编译和链接 C 编译器然后 SIGILL?

     2023-03-15     146

关键词:

【中文标题】为啥 C 程序会在运行时针对 C++ 库编译和链接 C 编译器然后 SIGILL?【英文标题】:Why would a C program compile and link with a C compiler against C++ libraries then SIGILL at runtime?为什么 C 程序会在运行时针对 C++ 库编译和链接 C 编译器然后 SIGILL? 【发布时间】:2016-01-21 05:47:24 【问题描述】:

我最近在 IBM AIX 上编写的第 3 方插件出现问题。追查需要相当长的时间。该插件采用 C 可执行文件的形式。可执行文件是针对 3rd 方库编译的。为强制升级提供了这些库的新版本。

当使用 IBM C 编译器 12.1 编译和链接时,我现有的代码将生成一个二进制文件,如果使用 OLSON 设置时区并使用 SIGILL 崩溃并且如果使用 POSIX 设置时区则没有可用的回溯。

使用调试 printfs 到日志文件并刷新日志文件,我能够相当快地追踪到调用 3rd 方 API 的崩溃。但是第 3 方提供商花了一些时间才提到新版本的 API 在他们自己的代码中引入了 C++ 库的使用。

问题已通过使用 IBM C 编译器进行编译但使用 IBM C++ 链接器 (xlC) 链接得到解决。

所以我的问题是:

1) 为什么 C 链接器无法生成有效的可执行文件?

必须已生成半有效的二进制文件,否则代码将无法在 OLSON 时区下运行。这意味着所有符号都存在并且任何名称修改都已处理(尽管可能不正确)

2) 如何判断编译器和链接器生成的二进制文件是否有效?

我能想到的唯一方法是通过单元测试尽可能充分地练习代码。

3) 如何防止不同代码出现类似情况?

我是否应该始终使用 C++ 链接器进行链接?这对我来说似乎不对。

抱歉,我无法发布代码,但我无权这样做。

【问题讨论】:

Off:插件应该是“共享对象”而不是“可执行文件”。 On:使用 C++ 是一种很快就会陷入困境的方法;例如,如果其中一个源模块是用 -D_THREAD_SAFE(或 -pthread)编译的,而另一个没有它,它们将无法一起工作。不同的 C++ 编译器(xlc 和 g++)也可能是二进制不兼容的。 (另外,在链接时,g++ 使用称为 collect2 的特殊组件,该组件在 AIX 上已损坏。) 注意:公平地说,如果没有 C++,您也可能会遇到二进制不兼容;例如,如果您尝试将使用大文件支持编译的模块与没有大文件支持编译的模块混合使用。 注意:如果插件有未解析的符号(检查dump -H libfoo.so的最后一行),主程序必须用-Wl编译,-brtllib 缺少此选项会导致奇怪的错误,包括 SIGILL。 'Plugin' 在这种情况下就是产品开发人员所说的。可执行文件作为完整的 exe 启动,并带有来自另一个服务器产品的主例程。 所以你的“插件”是一个独立的可执行文件。无论如何,如果它包含 C++,那么它的每个部分都应该用 C++ 编译器/链接器进行编译和链接。还要注意不兼容问题,例如线程安全是/否、大文件支持是/否、不同的编译器(-version)、不同版本的共享库、缺少 -Wl、-brtllib 等 【参考方案1】:

Zsigmond 有很多好话。我们至少需要查看链接行及其选项来帮助您。很多时候,开源链接带有“忽略未解析的符号”,因为它们不理解导入文件。因此,该链接将成功生成一个完全无用的二进制文件——因为这就是它被要求这样做的原因。

【讨论】:

在每种情况下,传递给 xlc 的唯一显式选项是 -g、-c 和 -o 加上相同的库文件集。这并不是说编译器没有将默认选项传递给链接器。我只是对链接器没有失败感到惊讶。

为啥即使使用 -cudart static 编译,库用户仍然需要链接到 cuda 运行时

】为啥即使使用-cudartstatic编译,库用户仍然需要链接到cuda运行时【英文标题】:Whyislinkingtocudaruntimestillnecessaryforlibraryuserevenwhencompilingwith-cudartstatic为什么即使使用-cudartstatic编译,库用户仍然需要链接到cuda运行时【发布时间】... 查看详情

与动态库链接导致的可执行运行时崩溃

】与动态库链接导致的可执行运行时崩溃【英文标题】:Executableruntimecrashcausedbylinkingwithdynamiclibrary【发布时间】:2013-12-2016:28:02【问题描述】:堆栈:MIPS、Linux、C、C++使用GNU工具编译和链接(基于x86构建MIPS)公平警告:我是C... 查看详情

Android Studio opencv C++ 在运行时编译链接库错误

】AndroidStudioopencvC++在运行时编译链接库错误【英文标题】:AndroidStudioopencvC++compilelinklibrarieserroratruntime【发布时间】:2015-09-3004:18:17【问题描述】:我正在使用带有NDK的Gradle2.6的AndroidStudio1.3.2。这是我的错误:dlopen("/data/app/face.r... 查看详情

c++中lib和dll的区别,生成以及使用详解

...生一个.lib文件动态库:动态链接库是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个DLL中,该DLL包含... 查看详情

Visual Studios 2012 更改运行时库会导致链接错误,使用 C++

...题描述】:我编写了使用Fico的BCLC++库来解决优化问题的程序。当我在VisualStudio2012中使用/MDd运行时库编译和运行代码时,一切都编译正常并且程序运行 查看详情

c/c++编译问题,静态库,动态库。

...是我自己现添加的,希望对你有帮助!报错"由于应用程序配置不正确,应用程序未能启动.重新安装应用程序可能会纠正这个问题"//------------------------------------------------------这个问题主要出现在XP环境下运行由VisualC++2003/2005... 查看详情

(转)c运行库c标准库windowsapi的区别和联系

...。  API函数API函数是操作系统为方便用户设计应用程序而提供的实现特定功能的函数,API函数也是C语言的函数实现的。区别他们之间区别是:API函数是针对操作系统的,C语言运行时函数则是针对C语言本身的。·1、运... 查看详情

用 C++ 链接 C 库

...我编译我的新项目,一切都很好,但是当项目被编译为C++程序时,它会为从dll文件导出的函数提供未解决的外部符号错误。我希望我的新项目是一个C++程序,但想链接一个编译为C程序的库 查看详情

在 C++ 程序上使用加载时或运行时动态链接时,如何在编译时解析引用?

】在C++程序上使用加载时或运行时动态链接时,如何在编译时解析引用?【英文标题】:Howreferencesareresolvedatcompiletimewhenusingload-timeorrun-timedynamiclinkingonC++programs?【发布时间】:2021-01-1522:45:58【问题描述】:我想我的问题很简单,... 查看详情

将静态本机库链接到托管 C++ 项目会在

】将静态本机库链接到托管C++项目会在【英文标题】:LinkingstaticnativelibrarytomanagedC++projectpullsunused(andunexpected)dependenciesin【发布时间】:2020-08-0617:57:58【问题描述】:简介:托管(/clr)C++项目(.dll)静态链接本机C++库(使用/MD编译)... 查看详情

尽管注释掉了所需的头文件,为啥这个 C++ 程序仍能编译和运行? [复制]

】尽管注释掉了所需的头文件,为啥这个C++程序仍能编译和运行?[复制]【英文标题】:WhydoesthisC++programcompileandrundespiterequiredheaderfilesbeingcommentedout?[duplicate]尽管注释掉了所需的头文件,为什么这个C++程序仍能编译和运行?[复制]... 查看详情

链接库函数

...ll)。无需提供源码。动态链接库与静态链接库动态链接库程序小,每次需要调用时访问库文件。依赖库运行。静态链接库程序大,是将相关库文件函数直接嵌入代码中。编译完成后不依赖库。 编译调用库函数的C代码时,需... 查看详情

从 C++ 链接到 C 库:为啥不总是需要 extern?

】从C++链接到C库:为啥不总是需要extern?【英文标题】:LinkingtoClibrariesfromC++:whyisn\'texternalwaysneeded?从C++链接到C库:为什么不总是需要extern?【发布时间】:2019-01-3012:06:07【问题描述】:通常要让C库在C++中工作,您必须将其包... 查看详情

开发工具详谈

学习QT时,遇到了MinGW,以前一直用vs编写程序,一直没遇到另一种编译器。根本没有形成一个概念。Mark。一、什么是工具集  我们在写代码时,如果没有各种开发工具集,我们写的各种代码只不过是一种TXT格式的文件。但有... 查看详情

在运行时链接外部库

...:05:51【问题描述】:我正在尝试编译使用FMOD和CMake的简单程序。编译似乎没问题,但我的应用程序因0xC0000135而崩溃,这是STATUS_DLL_NOT_FOUND我的CMakeList.txtcmake_minimum_required(VERSION3.7)project(fmod-t 查看详情

为啥要为 c 和 c++ 使用 gcc 和 g++ 编译器驱动程序

】为啥要为c和c++使用gcc和g++编译器驱动程序【英文标题】:whyusegccandg++compilerdriversforcandc++为什么要为c和c++使用gcc和g++编译器驱动程序【发布时间】:2018-04-1708:45:43【问题描述】:我已经将一个项目移植到了armcortexM7芯片上,并... 查看详情

为啥debug版本正确,release版本错误

一、Debug和Release编译方式的本质区别Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户... 查看详情

为啥 C 和 C++ 编译器在从未强制执行时允许函数签名中的数组长度?

】为啥C和C++编译器在从未强制执行时允许函数签名中的数组长度?【英文标题】:WhydoCandC++compilersallowarraylengthsinfunctionsignatureswhenthey\'reneverenforced?为什么C和C++编译器在从未强制执行时允许函数签名中的数组长度?【发布时间】... 查看详情