How to know where comes a stack corruption from in the destructor?
-
31-05-2021 - |
题
From some time now, I've been facing a problem and I didn't found a solution :(
I've a class like that:
template<typename Node, unsigned int Threads, unsigned int Size = 2, unsigned int Prefill = 50>
class HazardManager {
public:
HazardManager();
HazardManager(const HazardManager& rhs) = delete;
/* Some methods */
private:
Node* Pointers[Threads][Size];
std::list<Node*> LocalQueues[Threads];
std::list<Node*> FreeQueues[Threads];
/* Some private methods */
};
This class is used inside another class:
template<typename T, int Threads>
class AVLTree {
public:
AVLTree();
~AVLTree();
private:
Node* rootHolder;
HazardManager<Node, Threads, 3> hazard;
unsigned int Curren[Threads];
};
And the AVLTree class is allocated on the stack. When the AVLTree gets destroyed, I got a segmentation fault in the std::list destructor. Here is the output of valgrind:
==9336== Invalid read of size 8
==9336== at 0x419F69: std::_List_base<avltree::Node*, std::allocator<avltree::Node*> >::_M_clear() (list.tcc:74)
==9336== by 0x419645: std::_List_base<avltree::Node*, std::allocator<avltree::Node*> >::~_List_base() (stl_list.h:401)
==9336== by 0x418DF9: std::list<avltree::Node*, std::allocator<avltree::Node*> >::~list() (stl_list.h:458)
==9336== by 0x418E66: HazardManager<avltree::Node, 1u, 3u, 1u>::~HazardManager() (in /home/wichtounet/dev/btrees/bin/btrees)
==9336== by 0x418F19: avltree::AVLTree<int, 1>::~AVLTree() (AVLTree.hpp:154)
==9336== by 0x418D9A: void testST<avltree::AVLTree<int, 1> >(std::string const&) (test.cpp:110)
==9336== by 0x41831D: test() (test.cpp:180)
==9336== by 0x41CFF8: main (main.cpp:19)
==9336== Address 0x0 is not stack'd, malloc'd or (recently) free'd
In my opinion, it's a case of stack corruption, but I've no idea where that can comes from... There are no errors during the use of the class itself, only when it's get destructed.
Is there tool that can help find this error or tips that helps to find when this kind of corruption can come from ?
I'm using GCC 4.7 to compile my application with debug symbols and no optimization.
Thanks in advance for any help or idea
解决方案
Switch to boost::array
/ std::array
and use at
, you'll get an out_of_range
exception.
其他提示
It is possible you are overindexing HazardManager::Pointers
that corrupts the list, which you only realize when its destructor is trying to access memory that is invalid (as the pointer got garbled).