调试可能的内存损坏

时间:2018-03-30 17:31:00

标签: c++ debugging

我的应用程序中似乎存在内存损坏,但似乎我无法使用以下任何工具找到它的来源: gdb,valgrind,address sanitizer,rr (看起来像我的处理器太旧了。)

我发现了这个问题,因为我们的信号处理程序在访问特定内存时报告了一个信号。

Valgrind在说我读取大小为8(因为该内存是通过指针访问)时非常有帮助,而 asan 报告了指针,代码中的类型是A * ,实际上是一种不相关的B型。

可悲的是,我无法提供 sscce ,所以我想知道在这种情况下如何继续调试?还有其他可以尝试的工具吗?

  • 平台是RHEL linux内核版本3.10

  • 编译器GCC 6.3.1

1 个答案:

答案 0 :(得分:0)

我有一个建议如何继续。首先是一些假设:

  • 您知道如何重现该错误。
  • 它不是随机的腐败,而是在一个地方或至少是一个限制区域。

基本思想是您经常触发对导致信号的损坏区域的访问。这增加了在导致腐败的点附近检测到损坏的可能性。为此,我建议使用一个简单的对象来构建数据结构并验证它:

struct validator
{
    validator(data_structure const& data):
        m_data(data)
    {
        validate();
    }
    ~validator()
    {
        validate();
    }
    void validate()
    {
        // Code that walks over the data structure
        // and possibly trips over corruptions.
    }
    data_structure const& m_data;
};

只需在代码中添加此实例即可。当经历生成的崩溃时,您会发现有些发生在通常与该数据结构无关的区域,而其他发生在真正使用数据结构的代码中。这种区别完全没有意义,因为它检测到腐败这一事实并不意味着它会导致腐败!但是,如果您收集越来越多的这些崩溃,您会发现更有可能涉及某些代码,并且应该更密切地调查该代码。

重现错误的工作量越大,收集有意义的数据量就越困难。因此,能够重现您所做的事情以及您收到的结果变得非常重要。因此,我会将bug搜索移动到版本控制中的单独分支,并在版本控制中包含一个带有协议的文件。当然,该分支并不打算合并,但它提供了相关的上下文信息。