The code itself is extremely simple. I'm using Catch2 to unit test, (I really like its interface) and break into gdb
, but getting no useful information for a Seg. fault thrown by said simple code.
I know exactly what is causing the problem, but I don't know why, or how I would've gotten the offending line of code from gdb
(I've extensive usage with the Python equivalent, pdb
, but errors in Python seem to be a lot more straightforward).
Flop.hpp
#ifndef FLOP
#define FLOP
class Flop {
private:
int tiles_[200][200][200];
public:
Flop();
}
#endif
Flop.cpp
#include "Flop.hpp"
Flop::Flop() { }
test_Flop.cpp
#include "catch.hpp"
#include "Flop.hpp"
SCENARIO("I bang my head against a wall") {
Flop flop;
WHEN("I try to run this test") {
THEN("This program SEGFAULTs") {
REQUIRE(1==1);
}
}
}
The main.cpp contains everything it should, alongside the downloaded catch.hpp (as instructed by the tutorial).
I compile this with: g++ Flop.cpp test_Flop.cpp main.cpp -o run_test
and run it with gdb -ex run --args ./run_test -b
, which allows Catch2 to break into the debugger. The result is this:
Program received signal SIGSEGV, Segmentation fault.
0x0000555555566e9e in ____C_A_T_C_H____T_E_S_T____0() ()
With backtrace:
#0 0x0000555555566e9e in ____C_A_T_C_H____T_E_S_T____0() ()
#1 0x000055555557e15e in Catch::TestInvokerAsFunction::invoke() const ()
#2 0x000055555557d7b1 in Catch::TestCase::invoke() const ()
#3 0x0000555555577f0a in Catch::RunContext::invokeActiveTestCase() ()
#4 0x0000555555577c59 in Catch::RunContext::runCurrentTest(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) ()
#5 0x000055555557671b in Catch::RunContext::runTest(Catch::TestCase const&) ()
#6 0x00005555555797cc in Catch::(anonymous namespace)::TestGroup::execute() ()
#7 0x000055555557ab49 in Catch::Session::runInternal() ()
#8 0x000055555557a853 in Catch::Session::run() ()
#9 0x00005555555b6195 in int Catch::Session::run<char>(int, char const* const*) ()
#10 0x000055555558fdf0 in main ()
Ok. So, SIGSEGV
indicates that we tried to read/write to memory that a process does not have access to. If, in Flop.hpp, I instead say int tiles_[10][10][10]
, then everything works fine. So setting tiles_
to a larger size is somehow reserving a piece of memory that cannot be accessed? I'm new to C++ (and thus new to actually thinking about what's going on in the computer when I program something) so correct me if I'm wrong, but int tiles_[200][200][200]
shouldn't take much more than 32MB of memory, right?
So with this, I have a couple of questions:
- Why is this causing a Segmentation fault?
- How can I use
gdb
to get me to the offending line of code? The un-simplified version of this code is a few hundred lines total. Luckily, my problem was early on in the class's definition, but commenting everything out and (painstakingly) uncommenting line-by-line still took a while, and this is whatgdb
was meant to prevent!