将代码链接到exe时C ++程序崩溃,但是将代码编译到exe时工作正常,为什么呢?

时间:2019-06-05 11:57:09

标签: c++ compilation linker

我有一个程序可以在一个平台上长期运行。由于其成功,它将被移植到另一个平台。没问题,我以为是因为它是用标准C ++编写的...

我的方法(用伪CMake进行说明):

  • 通过采购特定于平台的工具链来设置开发环境,以确保定位正确的平台
  • 将所有核心业务逻辑分解到一个应用程序对象中,并从该对象中构建一个库(来自相同源代码的每个平台一个库):

    add_library(appLib STATIC app.cpp)
    target_link_libraries(appLib utilLib networkLib dbLib ${boostLibs})
  • 有一个main_a.cpp和另一个main_b.cpp,它们分别对平台a和b进行特定于平台的初始化,并让其中的main函数实例化应用程序对象。

    int main()
    {
        auto result = initAndDoPlatformStuff();
        App app(result);
        app.run();
    }
  • 指示编译器和链接器汇编可执行文件:

    if (Platform_A)
    add_executable(appExe main_a.cpp)
    else()
    add_executable(appExe main_b.cpp)
    endif()
    target_link_libraries(appExe appLib)

原则上,我猜这是一种完全有效的方法。但实际上,它是行不通的。在第二个程序崩溃后,崩溃几乎每次都不同。检查核心转储时,它有时会在标准库中崩溃,有时会在boost库中以及我的代码中崩溃,但这是胡说八道。程序似乎可以工作10次,但最终会崩溃。

但是,如果我使用相同的精确代码,则仅将其提取到其原始main.cpp文件中,然后以不同的方式将其构建在一起,如下所示:

int main()
{
    auto result = initAndDoStuff();
    processForever(result); // Business logic
}
add_executable(appExe main.cpp)
target_link_libraries(appExe utilLib networkLib dbLib ${boostLibs})

然后它起作用了!

我感到困惑和困惑。我怀疑它必须与代码布局有关,因此我尝试了PIC和PIE的不同变体,但没有成功。有没有可用的工具可让您全面了解二进制代码的布局?我知道nm,od,objdump,但是它们是低级的,我不知道要寻找什么... 无论如何,也许我走错了路,也许问题与完全不同的事情有关。是否有人会引起这种行为的任何预感?我还能如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

实际上,故障是我的。当然... 当我将代码重构为lib时,我确实尽力使所有细节正确无误,但显然我不够谨慎,在寻找问题时视而不见。
我最终发现的问题是,重构后我仍然将一个变量保留为局部变量,然后超出了范围,导致引用了释放的内存,这导致了各种不确定的行为。