我有一个程序可以在一个平台上长期运行。由于其成功,它将被移植到另一个平台。没问题,我以为是因为它是用标准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,但是它们是低级的,我不知道要寻找什么... 无论如何,也许我走错了路,也许问题与完全不同的事情有关。是否有人会引起这种行为的任何预感?我还能如何解决这个问题?
答案 0 :(得分:0)
实际上,故障是我的。当然...
当我将代码重构为lib时,我确实尽力使所有细节正确无误,但显然我不够谨慎,在寻找问题时视而不见。
我最终发现的问题是,重构后我仍然将一个变量保留为局部变量,然后超出了范围,导致引用了释放的内存,这导致了各种不确定的行为。