user12150819
user12150819

Reputation:

Segmentation fault debugger error message meaning?

I am learning c++ and I have a segmentation fault with my code. I ran the debugger and I got the following error message which I am struggling to understand.

Program received signal SIGSEGV, Segmentation fault. 0x0000000008002e3e in std::__uniq_ptr_impl<TreeNode<int>, std::default_delete<TreeNode<int> > >::_M_ptr (this=0x8) at /usr/include/c++/7/bits/unique_ptr.h:147 
147      pointer      _M_ptr() const { return std::get<0>(_M_t); }

Does this mean the segmentation fault is occurring in line 147 in my TreeNode class? If so, the line 147 is empty.

Can someone please clarify.

Edit: after following @HolyBlackCats advice I typed in bt and got the following message.

#0  0x0000000008002e3e in std::__uniq_ptr_impl<TreeNode<int>, std::default_delete<TreeNode<int> > >::_M_ptr (this=0x8) at /usr/include/c++/7/bits/unique_ptr.h:147  

#1  0x0000000008002680 in std::unique_ptr<TreeNode<int>, std::default_delete<TreeNode<int> > >::get (this=0x8) at /usr/include/c++/7/bits/unique_ptr.h:337

#2  0x0000000008001c55 in BinarySearchTree<int>::begin (this=0x7ffffffedf48) at tree.h:99

#3  0x0000000008000d98 in main () at TestTreeD.cpp:20

I still do not understand what this means.

Upvotes: 2

Views: 1484

Answers (2)

Chilly_Vanilly
Chilly_Vanilly

Reputation: 75

I would like to point out that this occurs if one is trying to initialize a static const-member through moving an initialized instance of std::unique_ptr into the uninitialized member, which will cause such behaviour.

Here an example of what I mean:

class SomeClass
{
private:
    static const std::unique_ptr<string> RESOURCE;

public:
    SomeClass() = default;
    ~SomeClass() {};

private:
    static std::unique_ptr<string>&& initResource()
    { return std::unique_ptr<string>(new string{"fdsa"}); }
};

const std::unique_ptr<string> SomeClass::RESOURCE = SomeClass::initResource();

int main(int argc, char const* argv[])
{
    return 0;
}

Try compiling this code with the debug-flag (with g++ it's the -g-flag) and run it using gdb, and you will see quite the similar behaviour as one may observe below:

Program received signal SIGSEGV, Segmentation fault.
0x0000555555555638 in std::__uniq_ptr_impl<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_ptr (this=0x0) at /usr/include/c++/7/bits/unique_ptr.h:147
147       pointer    _M_ptr() const { return std::get<0>(_M_t); }

Basically in order to fix this, simply remove the rvalue reference (<type>&&) from methods like SomeClass::initResource() and/or do not use things that enforce a moving operation such as std::move() in those situations where initialization is supposed to happen.

Upvotes: 0

Sam Varshavchik
Sam Varshavchik

Reputation: 118445

As the error message states, the segfault occurred when executing code compiled from line 147 of the C++ library header file.

The backtrace shows the execution stack at the point where backtrace occurs.

A backtrace does not always give you a full explanation for the reasons for your segfault. Unfortunately, C++ is not that easy. The backtrace only gives you the starting clues for investigating the reason for the crash. A backtrace is only the starting point for our debugging. Where you go from there depends on what you know and your experience.

Sometimes even the backtrace itself is garbage, because the stack was corrupted.

And at other times the backtrace will be good, but not have anything to tell you about the reason for the segfault, but it will tell you the how you wound up in that part of the code. So, for example, you would use this information to set a breakpoint earlier in the code, before the crash, and when execution stops there, you can analyze and inspect the values of all objects and variables, and see if anything seems out of place, or if there's something wrong. What's "something wrong" means is going to be entirely up to you to determine, based on the exact details of your application.

I could find only one clue that's apparent by inspecting your shown backtrace, that would be stack frame #1:

#1  0x0000000008002680 in std::unique_ptr<TreeNode<int>,
   std::default_delete<TreeNode<int> > >::get (this=0x8)
                                              ==========

According to this backtrace, the code is executing an object at memory address 0x8. This is, obviously, complete nonsense. It's quite common to see this of 0x0, a.k.a. a null pointer, when picking up the flaming wreckage of a backtrace. 0x8 is close enough to indicate memory corruption. Probably some object that has a unique_ptr as a class member, the pointer to this object is null, and the code is attempting to invoke a method of the unique_ptr, which is at offset 0x8 in the class that contains it.

So, at this point, the shown code most likely used a garbage pointer, or an uninitialized reference, or some other logical error to invoke a method through a bad pointer or reference.

Your next step would be to set a breakpoint wherever stack frame #2 is, that invoked some operation on some bogus unique_ptr it got somewhere. Based on what you see there, you will either find more clues, or, after inspecting the surrounding code, be able to determine the underlying bug.

Good luck.

Upvotes: 4

Related Questions