我有一个程序在一个平台上运行了很长时间。由于它的成功,它将被移植到另一个平台。没问题,我想因为它是用标准 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,但它们是低级的,我不知道要寻找什么...... 也许我走错了路,也许问题与完全不同的事情有关。有没有人预感到什么会导致这种行为?我还能如何解决这个问题?
最佳答案
其实,错在我。当然...
我在将代码重构为lib时确实试图将所有细节都正确无误,但显然我不够细心,在寻找问题时盲目。
我最终发现的问题是,我在重构后仍然将一个变量保留为局部变量,然后超出范围导致引用释放的内存,从而导致各种未定义的行为。
关于当代码链接到 exe 时 C++ 程序崩溃,但当代码编译成 exe 时工作正常,这是怎么回事?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56460040/