Those bogus adresses (0x00000002 and the like) are actually PC values, not SP values. Now, when you get this kind of SEGV, with a bogus (very small) PC address, 99% of the time it's due to calling through a bogus function pointer. Note that virtual calls in C++ are implemented via function pointers, so any problem with a virtual call can manifest in the same way.
An indirect call instruction just pushes the PC after the call onto the stack and then sets the PC to the target value (bogus in this case), so if this is what happened, you can easily undo it by manually popping the PC off the stack. In 32-bit x86 code you just do:
(gdb) set $pc = *(void **)$esp
(gdb) set $esp = $esp + 4
With 64-bit x86 code you need
(gdb) set $pc = *(void **)$rsp
(gdb) set $rsp = $rsp + 8
Then, you should be able to do a bt
and figure out where the code really is.
The other 1% of the time, the error will be due to overwriting the stack, usually by overflowing an array stored on the stack. In this case, you might be able to get more clarity on the situation by using a tool like valgrind
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…