Либо post-mortem debugging.
1. Компилируем программу с ключом -ggdb3
2. $ ulimit -c unlimited
Эта команда снимет лимит на размер создаваемых ядерных файлов (core.###, где ### - PID обвалившегося процесса), который по умолчанию 0 (не создавать)
3. $ gdb исполняемый_файл --core=тот_самый_core
Далее с помощью команд дебагера
bt
show threads, если программа многопоточная
t #, где # - номер потока
и снова bt
изучаем стеки потоков.
Поток, в котором произошла ошибка, будет, вероятнее всего, первым.
С помощью команды print можно посмотреть значения переменных.
Если в программе есть контейнеры STL, надо поискать скриптики для GDB, которые позволят поглядеть их в боле-мене вменяемом виде.
Рекомендую поставить DDD и пользоваться им, есть в репах.
Помимо gdb есть valgrind - ну очень полезный отладчик.