Следуя совету этого вопроса , я добавил #include <fenv.h>
и feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT);
к своему основному источнику и скомпилировал его, используя g++ -O0 -Wall -Wextra -Werror -g main.cpp -o main.o
.Все файлы в проекте скомпилированы таким образом, используя make.feenableexcept
был добавлен только к основному.Вещи связаны между собой одинаковыми -O0 и -g.Затем я запускаю исполняемый файл как gdb a.out
.Отладчик дает мне ожидаемое SIGFPE
, однако обратная трассировка не дает обычно полезной информации.Вместо этого я получаю листинг, подобный этому:
Program received signal SIGFPE, Arithmetic exception.
0x00002aaaabe19c0d in _amd_handle_error () from /lib64/libm.so.6
(gdb) bt
#0 0x00002aaaabe19c0d in _amd_handle_error () from /lib64/libm.so.6
#1 0x00002aaaabe19cca in _pow_special () from /lib64/libm.so.6
#2 0x00002aaaabdf6c12 in pow () from /lib64/libm.so.6
#3 0xbfc971b779361ea1 in ?? ()
#4 0x3fe85bf701f137d7 in ?? ()
#5 0x3fe914100cd71275 in ?? ()
#6 0x00007fffffffa420 in ?? ()
#7 0x00007fffffff9960 in ?? ()
#8 0x3fe7c514ca0e522d in ?? ()
#9 0x0000000000000000 in ?? ()
Если я пытаюсь посмотреть на кадры, я не получаю ничего полезного.В этом случае функция pow
используется много раз в области кода с ошибкой с плавающей запятой.Знание того, как я добрался до pow
, является здесь отсутствующей информацией.
Обычно, когда я использую -O0
и -g
, я получаю функции, файлы и номера строк, связанные с трассировкой.Если я устанавливаю точку останова, используя тот же исполняемый файл и обратную трассировку от точки останова, я получаю полезную информацию.
Breakpoint 1, SurfaceModel::ProcessGroups (this=0x7fffffff9f30) at source/SurfaceModel.cpp:398
398 vector<Group>::iterator it;
(gdb) bt
#0 SurfaceModel::ProcessGroups (this=0x7fffffff9f30) at source/SurfaceModel.cpp:398
#1 0x00000000006768e6 in MainLoop (logFile=...) at source/main.cpp:94
#2 0x0000000000676337 in main (argc=1, argv=0x7fffffffbe18) at source/main.cpp:41
Затем я добавляю *(int*)0=0;
к коду, чтобы вызвать ошибку сегмента, чтобы увидеть, было ли это связано ссигналы.Я также получил полезную информацию.
Program received signal SIGSEGV, Segmentation fault.
0x000000000061f42a in SurfaceModel::ClearGroupHeatRates (this=0x7fffffff9f30) at source/SurfaceModel.cpp:456
456 *(int*)0=0; // force a seg fault
(gdb) bt
#0 0x000000000061f42a in SurfaceModel::ClearGroupHeatRates (this=0x7fffffff9f30) at source/SurfaceModel.cpp:456
#1 0x0000000000676ba5 in MainLoop (logFile=...) at source/pilager.cpp:137
#2 0x0000000000676341 in main (argc=1, argv=0x7fffffffbe18) at source/pilager.cpp:41
Это, похоже, связано только с тем, что я делал с управлением с плавающей запятой.Я использую GDB 7.12, и это было скомпилировано с GCC 5.3.0.Есть ли способ сохранить информацию трассировки с помощью SIGFPE
?