c++ - 如何调试令人困惑的大代码?

标签 c++ debugging gdb sigabrt

我不是 C++ 程序员,但尝试调试一些复杂的代码。不是最好的先决条件,我知道...

所以我有一个 openfoam 求解器,它使用(包括)大量代码,我正在努力寻找真正的错误。我用

编译

SOURCE=mySolver.C ; g++ -m64 -Dlinux64 -DWM_DP -Wall -Wextra -Wno-unused-parameter -Wold-style-cast -O3 -DNoRepository -ftemplate-depth-100 -I/opt/software/openfoam/OpenFOAM-2.0.5/src/dynamicMesh/lnInclude {more linking} -I. -fPIC -c $SOURCE -o Make/linux64Gcc46DPOpt/mySolver.o

并且在使用适当的选项运行求解器之后,它在我的 return 语句之后(或同时)最后崩溃了:

BEFORE return 0

*** glibc detected *** /opt/software/openfoam/myLibs/applications/bin/linux64Gcc46DPOpt/mySolver: double free or corruption (!prev): 0x000000000d3b7c30 ***
======= Backtrace: =========
/lib64/libc.so.6[0x31c307230f]
/lib64/libc.so.6(cfree+0x4b)[0x31c307276b]
/opt/software/openfoam/ThirdParty-2.0.5/platforms/linux64/gcc-4.5.3/lib64/libstdc++.so.6(_ZNSsD1Ev+0x39)[0x2b34781ffff9]
/opt/software/openfoam/myLibs/applications/bin/linux64Gcc46DPOpt/mySolver(_ZN4Foam6stringD1Ev+0x18)[0x441e2e]
/opt/software/openfoam/myLibs/applications/bin/linux64Gcc46DPOpt/mySolver(_ZN4Foam4wordD2Ev+0x18)[0x442216]
/lib64/libc.so.6(__cxa_finalize+0x8e)[0x31c303368e]
/opt/software/openfoam/myLibs/lib/linux64Gcc46DPOpt/libTMP.so[0x2b347a17f866]
======= Memory map: ========
...

我的求解器看起来像(抱歉,我不能发布所有部分):

#include "stuff1.H"
#include "stuff2.H"

int main(int argc, char *argv[])
{
#include "stuff3.H"
#include "stuffn.H"

    while (runTime.run())
    {

        ...

    }

Info<< "BEFORE return 0\n" << endl;

return(0);
}

使用 gdb 运行求解器 setting set environment MALLOC_CHECK_ 2 yields to:

BEFORE return 0

Program received signal SIGABRT, Aborted.
0x00000031c3030265 in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x00000031c3030265 in raise () from /lib64/libc.so.6
#1  0x00000031c3031d10 in abort () from /lib64/libc.so.6
#2  0x00000031c3075ebc in free_check () from /lib64/libc.so.6
#3  0x00000031c30727f1 in free () from /lib64/libc.so.6
#4  0x00002aaab0496ff9 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() ()
   from /opt/software/openfoam/ThirdParty-2.0.5/platforms/linux64/gcc-4.5.3/lib64/libstdc++.so.6
#5  0x0000000000441e2e in Foam::string::~string (this=0x2aaaac0bd3c8, __in_chrg=<value optimized out>) at /opt/software/openfoam/OpenFOAM-2.0.5/src/OpenFOAM/lnInclude/string.H:78
#6  0x0000000000442216 in Foam::word::~word (this=0x2aaaac0bd3c8, __in_chrg=<value optimized out>) at /opt/software/openfoam/OpenFOAM-2.0.5/src/OpenFOAM/lnInclude/word.H:63
#7  0x00000031c303368e in __cxa_finalize () from /lib64/libc.so.6
#8  0x00002aaab2416866 in __do_global_dtors_aux () from /opt/software/openfoam/myLibs/lib/linux64Gcc46DPOpt/libTMP.so
#9  0x0000000000000000 in ?? ()
(gdb) 

我应该如何继续寻找错误的真正根源?

顺便说一句。我看到了thisthis这很相似但没有解决我的问题。 valgrind 对我来说也不能正常工作。我知道这与一些错误的(取消)分配有关,但我不知道如何真正找到问题。

/编辑

我还没有找到我的问题...

我认为我在上面发布的回溯(位置 #8)显示问题出在编译为 libTMP.so 的代码中。在 Make/options 文件中,我添加了选项 -DFULLDEBUG -g -O0。当时我认为可以跟踪错误,但我不知道如何。

非常感谢任何帮助!

最佳答案

如果您已经处理了所有编译器警告和 valgrind 错误,但问题仍然存在,那么分而治之

删除一半代码(使用 #if 指令,从 Makefile 中删除文件,或删除行并稍后使用源代码管理恢复)。

如果问题消失,则很可能是由您刚刚删除的内容引起的。或者,如果问题仍然存在,那么肯定是在仍然存在的代码中。

递归地重复该过程,直到您找到问题所在。

这并不总是有效,因为未定义的行为可能会在导致它的行之后出现。

但是您可以努力制作 minimal program that still has the problem .最终,您必须要么生成一个无法进一步简化的实际最小示例,要么找出真正的原因。

关于c++ - 如何调试令人困惑的大代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28346199/

相关文章:

c++ - 如果我在使用新程序和结束程序分配数据后没有调用 delete 运算符,会发生什么情况?

java - 在 Eclipse IDE 中调试 micronaut 应用程序

c - GDB,检查指向指针的指针

gcc - objcopy 和 dsymutil 有什么区别?

c++ - 为什么在 C++ 中为执行线程从未遇到过的局部变量声明分配堆栈空间?

c++ - 使用 unique_ptr 保护析构函数

C++ 纯虚函数的多重继承问题

debugging - 如何避免在 gdb 中重复输入相同的内容?

java - 在Eclipse中调试时,在返回之前可以查出返回值吗?

GDB:使用操作码检查指令