C++ 调试调试程序内部未发生的崩溃

C++ 调试调试程序内部未发生的崩溃,c++,debugging,stl,crash,C++,Debugging,Stl,Crash,我将一段单片代码拆分为动态加载的库和调用它的main()。除了stdc++,我没有使用其他库,也没有任何类,只是一个没有成员函数的模板结构。我没有显式分配任何内存,也没有删除或释放代码中的任何内容。我确实使用从列表中擦除对象 切换到library+main后,我会间歇性崩溃 ***glibc检测到***:free():无效指针: 从回溯来看,似乎有一个列表涉及到了itertor,但名称上的符号弄乱了,这让人很难确定 但是,它不会在gdb内部崩溃,valgrind也不会检测到任何内存损坏或泄漏 我

我将一段单片代码拆分为动态加载的库和调用它的
main()
。除了stdc++,我没有使用其他库,也没有任何类,只是一个没有成员函数的模板结构。我没有显式分配任何内存,也没有删除或释放代码中的任何内容。我确实使用从
列表中擦除对象

切换到library+main后,我会间歇性崩溃

***glibc检测到***:free():无效指针:

从回溯来看,似乎有一个列表涉及到了itertor,但名称上的符号弄乱了,这让人很难确定

但是,它不会在gdb内部崩溃,valgrind也不会检测到任何内存损坏或泄漏

我以前没有构建过共享库。这就是我正在使用的

g++-fPIC-sharedlibrary_src.cpp-o libblaH.so

g++main.cpp-lblaH

整个库是一个单一的源文件,库函数被封装在<代码>外“C”< /C>块中,使C用户可以访问,但现在我用g++作为C++代码编译主(./p>)。 现在,当我添加优化选项时,

-O2
(特别是)我开始崩溃

我试过
electricfence
它说无效指针不是由malloc分配的


如果您能给我一些建议,告诉我如何找到这个bug,我将不胜感激。我的感觉是,我在某个地方使列表迭代器失效,但我不确定如何失效。我认为它们不能无效,除了删除的条目。

出于某种原因,这个变量对我来说是未初始化的。许多年前,当我按小时向公司收费以帮助调试这样的崩溃时,有一半的时间,问题是未初始化的变量

我会采用的方法是:

  • 系统地初始化所有变量,并在声明时全部初始化。绝对没有例外
  • 查找无效迭代器。i、 e.指向已擦除对象的迭代器无效,不应使用
  • 寻找变量劫持。i、 e.具有相同名称的变量在同一翻译单元中运行良好,但在单独的翻译单元中不起作用
  • 查找不安全的函数调用,如sprintf,其中格式字符串与参数不匹配
  • 使用#pragma在部分代码中有选择地禁用优化,以缩小问题范围。有点像二进制搜索;禁用上半部分,仍然崩溃,下半部分出现问题,禁用上半部分和下半部分的1/2

  • 我假设不涉及多个线程。当涉及线程时,更多的事情可能会出错。当我受雇于客户站点时,我总是让他们在启动任何调试器之前先初始化所有变量。50%的时间我可以在第1步后回家。

    出于某种原因,我对这个未初始化的变量发出尖叫。许多年前,当我按小时向公司收费以帮助调试这样的崩溃时,有一半的时间,问题是未初始化的变量

    我会采用的方法是:

  • 系统地初始化所有变量,并在声明时全部初始化。绝对没有例外
  • 查找无效迭代器。i、 e.指向已擦除对象的迭代器无效,不应使用
  • 寻找变量劫持。i、 e.具有相同名称的变量在同一翻译单元中运行良好,但在单独的翻译单元中不起作用
  • 查找不安全的函数调用,如sprintf,其中格式字符串与参数不匹配
  • 使用#pragma在部分代码中有选择地禁用优化,以缩小问题范围。有点像二进制搜索;禁用上半部分,仍然崩溃,下半部分出现问题,禁用上半部分和下半部分的1/2

  • 我假设不涉及多个线程。当涉及线程时,更多的事情可能会出错。当我受雇于客户站点时,我总是让他们在启动任何调试器之前先初始化所有变量。50%的时间我可以在步骤1后回家。

    如果将所有代码放入一个单片编译单元,则不会显示错误?@Walter是的,这是正确的。嗯,在我运行它的10~15次中,它都没有出现过。但即使是库版本也不会总是崩溃,当我在标志中有-O2时,每5次就会崩溃一次,如果没有设置优化标志,则不会崩溃。如果调试器不工作,您可以使用
    printf
    跟踪错误,而无需附加调试器,因此,您可以看到哪个对象正在使用
    free
    函数。请尝试
    c++filt
    来请求stacktrace中的名称,这可能会对您有所帮助。我知道这种类型的错误(我自己也有过很多次),但请记住错误消息实际上并没有多大帮助。但你很可能已经把不该写的东西写进了记忆。如果将所有代码放在一个单片编译单元中,我通常使用打印方法而不是调试(因为调试器中的事情并不总是一样的,正如您所注意到的,但是打印语句也可能会更改代码--编译器可以重新排序,然后突然所有代码都可以工作),错误没有显示?@Walter是的,没错。嗯,在我运行它的10~15次中,它都没有出现过。但即使是库版本也不会总是崩溃,当我在标志中有-O2时,每5次就会崩溃一次,如果没有设置优化标志,则不会崩溃。如果调试器不工作,您可以使用
    printf
    跟踪错误,而无需附加调试器,因此,您可以看到哪个对象正在使用
    free
    函数。请尝试
    c++filt
    来请求stacktrace中的名称,这可能会对您有所帮助。我知道这种类型的错误(我自己也有过很多次),但请记住错误消息实际上并没有多大帮助。但你很可能已经把不该写的东西写进了记忆。我通常使用打印方法而不是调试(因为