linux 损坏的堆栈根本原因检测

wrrgggsh  于 2023-04-20  发布在  Linux
关注(0)|答案(2)|浏览(189)

我有一个多线程应用程序中损坏的堆栈问题。
有一个类:

class A {
public:
/// some public methods
private:
some references to other objects like:
ClassA& ref;
ClassB& ref2;
...
some fields like:
std::map<std::string, enumClass> ...
std::mutex ...
std::map<std::string, someClass> ...
std::mutex again some mutex
std::map<string, std::pair<ClassB, someEnum>> corrupted_map;
bool isTrue;
};

更具体地说,这个问题是一个分段错误。这个分段错误是由corrupted_map上的operator[]引起的。在调试会话之后,似乎stl树的一个字段在corrupted_map上没有任何操作的情况下被更改了。这就是为什么我认为这是堆栈内存损坏。stl黑红树头的右叶指向不可访问的内存。进一步的调查显示,另一个map操作损坏了corrupted_map。此外,另一个问题是,重现提到的问题需要大约30分钟,并需要大量的流量。
分析核心转储是没有意义的,因为损坏发生在核心转储前1- 2分钟。
各位Maven的问题是:如何检测堆栈内存损坏来源?其他工具?
我试着:
ASAN地址消毒程序-在segfault之前未检测到任何内容
GDB -太慢,应用程序在复制之前被杀死,很多看门狗,时间依赖等
valgrind -也太慢/和单元测试-未检测到任何内容
静态代码分析器-未检测到任何内容
TSAN -线程消毒程序-修复了一些检测到的问题,但没有帮助
我发现一个线程每2 ms扫描一次stl树字段+额外检查可疑方法,但很可能导致上述问题的Map操作也已损坏。

iecba09b

iecba09b1#

如何检测堆栈内存损坏来源?
几乎可以肯定这不是堆栈损坏,而是堆损坏:map的 * 元素 * 都不在堆栈上。
ASAN地址消毒程序-在segfault之前未检测到任何内容
这是令人惊讶的-- ASan通常非常擅长检测堆损坏。
我有几种方法来解决这个问题:
1.运行ASan测试10次或更多次。
1.调整ASan runtime flags,特别是quarantine_size_mb
为什么(1)?有时候ASan检测到一个问题并开始报告它,但是在它可以完成之前,另一个线程命中SIGSEGV并导致进程死亡而没有任何报告。重复测试100次可能会在其中一个中得到一个报告;一个就够了!
为什么(2)?正如标志描述所述,如果您正在执行大量分配,则可能无法检测到use-after-free。
您还可以启用detect_stack_use_after_return,它可以检测现有的错误,尽管我怀疑您在这里真的有堆栈问题。
Henri Menke建议使用-D_GLIBCXX_ASSERTIONS-D_GLIBCXX_DEBUG也是非常好的。

oxf4rvwz

oxf4rvwz2#

解决了。实际上我只使用了-D_GLIBCXX_ASSERTIONS,但是D_GLIBCXX_DEBUG显示了它的强大功能。错误是非常基本的-写入指向前一个map的end(等于.end())的迭代器。是的,你们是对的,这是堆的损坏-而不是堆栈。

相关问题