4

I'm learning how to debug with gdb on my mac and after finding a segmentation fault I wanted to use it to learn. I'm using gdb 8.0.1 and gcc 7.2.0 both from homebrew, I'm compiling with -ggdb and running gdb directly from my makefile through gdb -ex run ./main.

I open the game, I open a menu inside it, and when I try close it it crashes because I do this in WindowsObject.cpp :

WindowObject_CraftingGrid::~WindowObject_CraftingGrid(){
   for (unsigned i = 0; i < gridSlots_.size(); i++) {
      for (unsigned j = 0; j < gridSlots_[0].size(); i++) { //i++ instead of j++, this leads to the crash
         delete gridSlots_[i][j];
      }
   }
}

Gdb says:

(gdb) bt
#0  0x0000000100023a80 in WindowObject_Image::Draw (this=0x300000000) at src/WindowObjects.cpp:620
#1  0x0000000100023ae2 in WindowObject_Image::setImage (this=0x100a9e980, img=0x0) at src/WindowObjects.cpp:629
#2  0x000000010001d5f7 in WindowMain::AddSection (this=0x100a04ce0, n=28672) at src/Window.cpp:263
#3  0x0000000100033765 in LoadLibrary () at src/main.cpp:781
#4  0x0000000100030b25 in DrawGUI () at src/main.cpp:465
#5  0x0000000100031534 in DrawGUI () at src/main.cpp:501
#6  0x00000001006eae27 in ?? ()
#7  0x0000700001875ef0 in ?? ()
#8  0x00007fff40b796d8 in ?? ()
#9  0x0000000000000000 in ?? ()

And this is totally wrong because it leads to nothing useful to solve the bug because it does not point to the right objects and lines.

I discovered this bug from visual studio on my windows machine because the call stack there was quite clear:

project.exe!std::vector<std::vector>WindowObjects_Slot * //Other stuff
project.exe!WindowObject_CraftingGrid::~WindowObject_CraftingGrid() Line 348
project.exe!WindowMain::~WindowMain() Line 234
project.exe!KeyPressed(int KeyCode) Line 566
project.exe!gameloop() Line 181
project.exe!main(int argc, char ** argv) Line 321)
elkiwy
  • 59
  • 5
  • 1
    I suspect that MSVC has instrumented `std::vector` for the debug build so that it fails early by throwing an exception. Perhaps the instance that is being debugged with gdb wasn't compiled with the same traps? Please share the command line that the first instance was built with. – wally Oct 06 '17 at 14:03
  • 1
    Often segfaults show up a lot later than whatever problem actually caused them. Assigning an invalid value to a pointer doesn’t crash the program even though it’s the actual bug; dereferencing the pointer causes the crash, but it can happen arbitrarily later. – Daniel H Oct 06 '17 at 14:07
  • Sorry but I don't know what you mean by "same traps"... Anyway the code is exactly the same between the 2 machines, but on windows I use visualstudio and on mac I use terminal+makefile+gcc+gdb to build so I guess that something is different between the two version of the executable, but the main problem is why gdb backtrace spits out such weird informations... – elkiwy Oct 06 '17 at 14:07
  • 1
    I suspect @rex means that the Windows `vector` code in debug mode has checks to see if something invalid is happening. The GCC ones apparently don’t, with the compilation flags you used, so they catch the issue later. What is the line in the makefile which calls GCC? – Daniel H Oct 06 '17 at 14:10
  • This is the exact output of the making process on mac `|| gcc-7 -Wall -ggdb -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -c -o obj/Block.o src/Block.cpp || ***other .cpp files compilation*** || gcc-7 -o main ***all the .o files*** pkg-config --cflags --libs ***all the allegro libs*** -I/usr/local/Boost/Builded/include/ /usr/local/Boost/Builded/lib/libboost_serialization-libstdc++.a /usr/local/Boost/Builded/lib/libboost_filesystem-libstdc++.a /usr/local/Boost/Builded/lib/libboost_system-libstdc++.a /usr/local/Cellar/gcc/7.2.0/lib/gcc/7/libstdc++.a` – elkiwy Oct 06 '17 at 14:12
  • See [traps](https://www.google.com/search?q=c%2B%2B+compiler+debug+traps) and [STL bounds checking with gcc](https://stackoverflow.com/a/5594728/1460794). – wally Oct 06 '17 at 14:16

1 Answers1

5

And this is totally wrong

No, it's not: it's where your application actually crashes on this platform.

because it leads to nothing useful to solve the bug

You have a heap corruption bug. Heap corruption bugs are like that: your application may crash some time after heap corruption, in an arbitrary place.

In addition, the stack trace is not useless: it tells you that this == 0x300000000, which is not a reasonable value for this, and therefore you are looking at some kind of heap corruption.

There are many ways to debug similar problems: debug malloc, Address Sanitizer and Valgrind among them.

Building with -D_GLIBCXX_DEBUG enables debugging mode in GCC STL, and would likely also point you straight at the bug.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362