gpt4 book ai didi

c++ - 如果 sanitizer 没有显示任何内容,我该如何调试内存崩溃?

转载 作者:行者123 更新时间:2023-12-02 07:19:31 27 4
gpt4 key购买 nike

我有一个复杂的应用程序在退出时崩溃。我无法通过最小的示例重现错误。当在应用程序退出时调用类的析构函数并且共享指针成员被破坏时,就会发生崩溃。我基本上在做的是这样的:

// plugin (.so loaded at runtime)
// called during application run
void SomePluginClass::foo()
{
auto ptr = std::make_shared<int>();
libraryObj.bar(ptr);
}

// library (.so linked to the executable and the plugin)
// SomeLibraryClass.hpp
class SomeLibraryClass
{
public
// ... some other code

~SomeLibraryClass();
void bar(std::shared_ptr<int> ptr);

private:
std::shared_ptr<int> m_ptr{};
}

// SomeLibraryClass.cpp
// called during application run
void SomeLibraryClass::bar(std::shared_ptr<int> ptr) { m_ptr = ptr; }

// called on application exit and cleanup
SomeLibraryClass::~SomeLibraryClass()
{
// crash happens here
// use_count shows 1
// reset() used here for debugging purposes as it causes the same crash as implicit destructor call
m_ptr.reset();
}

我尝试使用 Valgrind 运行应用程序和 gcc address sanitizer - 它们在运行时都不会显示任何问题,但会在崩溃后显示问题。例如,这里有一些 sanitizer 的输出:
==11744==ERROR: AddressSanitizer: SEGV on unknown address 0x7f56b3ba0c20 (pc 0x555ac6680ead bp 0x7ffc9d3ce920 sp 0x7ffc9d3ce910 T0)
==11744==The signal is caused by a READ memory access.
#0 0x555ac6680eac in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/7/bits/shared_ptr_base.h:154
#1 0x555ac6680b33 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/7/bits/shared_ptr_base.h:684
#2 0x7f56e5e562cd in std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/7/bits/shared_ptr_base.h:1123
#3 0x7f56e5e56574 in std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2>::reset() /usr/include/c++/7/bits/shared_ptr_base.h:1235

什么数字 (pc 0x555ac6680ead bp 0x7ffc9d3ce920 sp 0x7ffc9d3ce910 T0)意思是?

我还能做些什么来找到崩溃源?

最佳答案

What does numbers (pc 0x555ac6680ead bp 0x7ffc9d3ce920 sp 0x7ffc9d3ce910 T0) mean?



在崩溃时(由尝试访问地址 0x7f56b3ba0c20 引起),程序计数器 (PC)、帧指针 (BP) 和堆栈指针 (SP) 寄存器的值为 0x555ac6680ead , 0x7ffc9d3ce9200x7ffc9d3ce910分别。

程序计数器值对应于 std::_Sp_counted_base<...>::_M_release()功能。

我们不知道崩溃地址 0x7f56b3ba0c20 在哪里来自。它不在当前堆栈指针附近,看起来不像堆地址(尽管它可能是),也不像随机垃圾。 ASan 也不知道这个地址是从哪里来的。

一种可能的解释:地址在堆上,然后被删除并移至隔离区(ASan 用它来告诉您有关悬空访问的信息),但随后其他 delete 超出了隔离区容量s,导致 ASan “忘记”它对该地址的了解(ASan 无法永远保留有关每个已删除内存块的信息 - 这会导致您的内存不足)。

您可以尝试使用以下方法增加 ASan 隔离缓冲区的大小:
ASAN_OPTIONS=quarantine_size_mb=4096

(默认为 256,增加直到内存不足或 ASan 告诉您实际上正在访问悬空内存)。

关于c++ - 如果 sanitizer 没有显示任何内容,我该如何调试内存崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59864143/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com