Если программа заканчивается ошибкой сегментировангия (segmentation fault) или ошибкой выполнения арифметической операции, то точное место возникновения ошибки можно выяснить с помощью отладчика gdb.
Рассмотрим такой пример программы.
int main(void) {
double sum;
int k;
for(k = 1; k < 100; k++) {
sum += (1.0 / (5353 + 5199*k - 153*k*k + k*k*k));
}
return 0;
}
Если откомпилировать (gcc gdb.c) и запустить (./a.out) эту программу, то можно увидеть примерно следующее:
$ ./a.out Исключение в операции с плавающей точкой (сделан дамп памяти)
Для выяснения причин ошибки воспользуемся отладчиком. Сначала
программу нужно откомпилировать с включенной отладочной
информацией. Это делается обычной командой компиляции с добавлением
ключа -g. Например: gcc -g gdb.c
Далее выполняем нашу программу "под отладчиком": gdb -q a.out
$ gdb -q a.out Reading symbols from a.out...done. (gdb)Сейчас выполняется программа gdb, в которую загружен наш выполняемый файл a.out. Надпись (gdb) означает, что нужно ввести команду отладчика (например, help). Введем команду run, которая запускает загруженный в отладчик выполняемый файл (нашу программу). Только после ввода команды run наша программа начинает выполняться. До этого ее код был только загружен в отладчик. В результете получим что-то такое:
$ gdb -q a.out Reading symbols from a.out...done. (gdb) run Starting program: /home/serg/tmp/a.out Program received signal SIGFPE, Arithmetic exception. 0x0000000000400579 in main () at gdb.c:7 7 sum += (1000 / (5353 + 5199*k - 153*k*k + k*k*k)); (gdb)Это означает, что ошибка произошла в функции main, строка 7 файла gdb.c. Для понимания сути ошибки желательно знать значения переменных в момент наступления ошибки. Для этого в gdb есть команда print (сокращенно p), которая распечатывает значение заданного выражения. Например,
$ gdb -q a.out Reading symbols from a.out...done. (gdb) run Starting program: /home/serg/tmp/a.out Program received signal SIGFPE, Arithmetic exception. 0x0000000000400579 in main () at gdb.c:7 7 sum += (1000 / (5353 + 5199*k - 153*k*k + k*k*k)); (gdb) print k $1 = 53 (gdb) p k $2 = 53 (gdb) p (1000 / (5353 + 5199*k - 153*k*k + k*k*k)) Division by zero (gdb) p (5353 + 5199*k - 153*k*k + k*k*k) $3 = 0 (gdb) quit $Теперь ясно, что выражение (5353 + 5199*k - 153*k*k + k*k*k) обратилось в ноль при k=53. Команда quit завершает работу отладчика и возвращает управление оболочке операционной системы.