Segmentation Fault程序编译成共享库但不是静态的

时间:2016-12-13 14:15:05

标签: c++ shared-libraries static-libraries static-linking infiniband

这可能是一个有点元的问题,因为我认为我的问题源于缺乏关于共享库和静态库的知识。

我正在使用infiniband在服务器/客户端系统上工作,作为学习练习/准备即将开始的工作计划。最初我有2个可执行文件,每个可执行文件都包含一些相同的源代码,因此我将它们分成公共文件(RDMAConnectionManager.cpp和RDMAConnection.cpp及其标题)。

在某个地方,我决定将这些文件作为库,这样我就可以确保我的服务器和客户端使用相同的低级代码。我一直使用共享库,所以我按照标准去做事情,通过cmake创建共享库。

问题是,一旦我这样做,我就会在库 rdmacm 提供的函数中得到分段错误,特别是 ib_verbs 函数。我认为它可能与链接顺序有关,但我没有改变任何帮助。

一时兴起,我将它从SHARED更改为STATIC库。这非常有效!我对静态的理解是它包含了它链接的库中的所有符号,而共享则没有。然而,既然我发现了这个棘手的问题,我觉得我错过了一些东西。

我已经做了一些阅读,并且对这些差异感到更加自在,但是我仍然不知道导致这个问题的原因(或者将来如何看待它)。有谁知道为什么会发生这样的事情?

1 个答案:

答案 0 :(得分:0)

您应该澄清SegFault的原因,例如使用gdb运行程序并确定发生段错误的位置。 在许多情况下,您可能有内存错误,内存错误是本机应用程序中非常常见的问题,您应该避免它们。但是你可以问一下,在某些情况下,内存错误会如何显示SegFault。 答案是关于程序的内存映射,如果更改代码(添加或删除某些内容)或在不同的编译器或不同的开关下编译它,您可能会得到不同的内存映射。 例如,调试或发布版本,或者在您的情况下,共享或静态构建可能在生成的二进制文件的内存映射方面有所不同。

那么不同的内存映射会如何导致SegFault?如果您的代码中存在内存问题,例如越界访问,无效写入或无效读取,根据二进制文件的内存映射,它可能生成或不生成SegFault,实际上您可能已经从为缓冲区保留的区域中访问了字节但突然这个out访问会进入您保留的另一个缓冲区或内存区域,并且您没有看到没有SegFaults(您的代码仍有问题)。 对于不同的构建,内存区域或内存映射的顺序可能会发生变化,这就是您在不同构建中获得SegFault的原因。