Сам код чрезвычайно прост. Я использую Catch2 для модульного тестирования (мне очень нравится его интерфейс) и разбиваю на gdb
, но не получая никакой полезной информации для Seg. ошибка, вызванная указанным простым кодом.
Я точно знаю, что вызывает проблему, но я не знаю, почему или как я мог получить вызывающую ошибку строку кода от gdb
(у меня использование с эквивалентом Python, pdb
, но ошибки в Python кажутся намного более простыми).
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);
}
}
}
main.cpp содержит все необходимое вместе с загруженным файлом catch.hpp (как указано в руководстве).
Я компилирую это с помощью: g++ Flop.cpp test_Flop.cpp main.cpp -o run_test
и запускаю с помощью gdb -ex run --args ./run_test -b
, что позволяет Catch2 проникнуть в отладчик. Результат таков:
Program received signal SIGSEGV, Segmentation fault.
0x0000555555566e9e in ____C_A_T_C_H____T_E_S_T____0() ()
С обратной трассировкой:
#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 ()
В порядке. Итак, SIGSEGV
указывает на то, что мы попытались прочитать/записать в память, к которой у процесса нет доступа. Если в Flop.hpp вместо этого сказать int tiles_[10][10][10]
, то все работает нормально. Таким образом, установка большего размера для tiles_
каким-то образом резервирует часть памяти, к которой нельзя получить доступ? Я новичок в C++ (и, следовательно, новичок в том, чтобы думать о том, что происходит на компьютере, когда я что-то программирую), так что поправьте меня, если я ошибаюсь, но int tiles_[200][200][200]
не должен занимать больше 32 МБ памяти, верно?
В связи с этим у меня есть пара вопросов:
- Почему это вызывает ошибку сегментации?
- Как я могу использовать
gdb
, чтобы добраться до оскорбительной строки кода? Неупрощенная версия этого кода состоит всего из нескольких сотен строк. К счастью, моя проблема была в начале определения класса, но закомментировать все и (кропотливо) раскомментировать строку за строкой по-прежнему требовалось некоторое время, и это то, чтоgdb
должно было предотвратить!