GDB "Программа вышла нормально", когда это не должно - PullRequest
2 голосов
/ 10 декабря 2011

Я отлаживаю код ANSI C с помощью gcc44 и gdb на 64-битном сервере Linux CentOS 5.7.

В середине одной из моих функций у меня есть цикл for, который зацикливается 192 раза (там2 строки кода в цикле).Если я установлю gdb с точкой останова в начале цикла for, я могу пройти через цикл for все 192 раза, и он выйдет из цикла for и перейдет к следующей строке кода после цикла for.Это все пошаговое выполнение кода в gdb с использованием "s" или "n".Все отлично работает

Теперь, вместо того, чтобы переходить через цикл for с помощью "s" или "n", чтобы перейти к следующей строке кода после цикла for, я запускаю gdb, а затем устанавливаю точку останова на строке сразу послеконец цикла.Если я затем нажму "c" в GDB, это даст мне "Программа завершилась нормально".Я ожидал, что GDB остановится на этой точке останова, расположенной в строке кода сразу после цикла for.(!?)

В качестве другого эксперимента я узнал, что gdb успешно останавливается на любой точке останова, установленной в любой строке после строки кода, следующей сразу за циклом for.

Возможно, у других был такой опыт, судя по таким вопросам (здесь есть 2 дополнительных ссылки):

Ошибка GDB "Программа завершилась нормально"

Это повторяется в GDB.Не копаясь в рассматриваемом коде, кто-нибудь видел такое поведение раньше и / или есть идеи, что я могу проверить?

РЕДАКТИРОВАТЬ 1

Если я добавлю printf("\n"); в строку точки останова, которая вызывает проблемы выше, переместив то, что раньше было в этой строке, на одну строку ниже этого кода printf, тогда все работает нормально(например, GDB останавливается на строке printf).

Я даже могу успешно установить точку останова на ранее проблемной строке кода, о которой идет речь, которая теперь является следующей строкой после строки printf.Weird!

1 Ответ

1 голос
/ 20 декабря 2011

Ваш компилятор подшучивает над вами.

Ну, не совсем, но это не совсем то, что вы подозреваете.

Первая принципиальная концепция компилятора состояла бы в том, чтобы последовательно превращать каждую строку C в одну или несколько инструкций сборки и выполнять сборку в том же порядке, что и код C.

На самом деле компилятор реорганизует вещи, чтобы оптимизировать их по скорости или пространству. Если считается, что инструкция не оказывает никакого влияния на состояние программы, ее можно полностью удалить. Таким образом, когда вы говорите GDB прервать эту строку, хорошо ... нет инструкции по сборке с отладочной информацией, указывающей на эту строку C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...