Отладка с помощью gdb и gfortran - FPE

Я отлаживаю большую числовую программу, к которой я добавил. Он написан в fortran90, скомпилирован с gfortran (последняя версия доступна для Mac), и я отлаживаю его с помощью gdb (опять же последней версии для Mac).

В моих добавлениях есть ошибка, и я пытаюсь найти ее, что ясно, так как запуск программы не дает ожидаемого результата. Когда я запускаю его в gdb, я получаю следующий вывод в конце:

Note: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG IEEE_DIVIDE_BY_ZERO IEEE_UNDERFLOW_FLAG IEEE_DENORMAL [Inferior 1 (process 83843) exited normally]

Я хотел бы точно определить, где именно происходит этот FPE, но кажется, что исключение с плавающей запятой не приводит к сбою программы. Я проверил это, явно разделив на 0 в моем коде - это не заставило программу перестать работать, но привело к неожиданному поведению.

Каков правильный флаг для gdb или gfortran, чтобы гарантировать, что программа перестанет работать (в идеале, с backtrace), когда она достигнет исключения с плавающей запятой? Я пробовал следовать инструкциям здесь, но он ничего не изменил.

Ответ 1

Возможно, вам нужно добавить эти флаги при компиляции кода:

gfortran -g -fbacktrace -ffpe-trap=zero,overflow,underflow youcode.f90 -o run.exe



Объяснение флагов компилятора из руководства gfortran:

-g       

включить отладочные данные

-fbacktrace

Укажите, что при возникновении ошибки времени выполнения или испускании смертельного сигнала (ошибка сегментации, недопустимая инструкция, ошибка шины или исключение с плавающей запятой) библиотека времени выполнения Fortran должна выводить обратный след ошибки. Эта опция влияет только на компиляцию основной программы на Фортране.

-ffpe-trap=list

Укажите список исключений IEEE при возникновении исключения с плавающей запятой (FPE). В большинстве систем это приведет к отправке сигнала SIGFPE и прерыванию работы программы, в результате чего будет создан файл ядра, полезный для отладки. list - это (возможно, пустой) список разделенных запятыми следующих исключений IEEE: invalid (недопустимая операция с плавающей запятой, например SQRT (-1.0)), zero (деление на ноль), overflow (переполнение в операции с плавающей запятой), underflow (недополнение в операции с плавающей запятой), precision (потеря точности во время операции) и denormal (операция вызвала ненормальное значение). Некоторые подпрограммы в библиотеке времени исполнения Fortran, такие как ‘CPU_TIME, могут вызывать исключения с плавающей запятой, когда используется ffpe-trap = precision. По этой причине использование ffpe-trap = precision не рекомендуется.

Взгляните на эти два места для получения дополнительной информации:

https://gcc.gnu.org/onlinedocs/gcc-4.3.2/gfortran.pdf http://faculty.washington.edu/rjl/uwamath583s11/sphinx/notes/html/gfortran_flags.html