Почему GDB переходит непредсказуемо между строками и печатает переменные как “<значение, оптимизированное>”?

Только для добавления к тому, какие сказанные tvanfosson, много шаблонов выглядят одинаково до реализации. Таким образом, много сделайте, чтобы Вы создали интерфейс где, возможно, не было того прежде в Вашем коде, и затем создайте набор реализаций того интерфейса. Различие находится в их цели и как они используются.

83
задан Ciro Santilli 新疆改造中心法轮功六四事件 2 July 2017 в 08:45
поделиться

7 ответов

Для отладки оптимизированного кода изучите ассемблер / машинный язык.

Используйте режим GDB TUI. Моя копия GDB включает его, когда я набираю минус и Enter. Затем введите Cx 2 (удерживая Control и нажмите X, отпустите оба и нажмите 2). Это поместит его в разделенный исходный код и дисплей разборки. Затем используйте stepi и nexti для перемещения одной машинной инструкции за раз. Используйте Cx o для переключения между окнами TUI.

Загрузите PDF-файл о машинном языке вашего процессора и соглашениях о вызове функций. Вы быстро научитесь распознавать, что делается с аргументами функции и возвращаемыми значениями.

Вы можете отобразить значение регистра, используя команду GDB, например p $ eax

114
ответ дан 24 November 2019 в 08:43
поделиться

Объявить найдено как «изменчивое». Это должно указать компилятору НЕ оптимизировать его.

volatile int found = 0;
38
ответ дан 24 November 2019 в 08:43
поделиться

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

Compile без оптимизаций?

11
ответ дан 24 November 2019 в 08:43
поделиться

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

int a = SomeFunction();
bool result = --a >= 0; // use subtraction as example computation
if ( result ) 
{
   foo(); 
}
else
{
   bar();
}
return;

Обычно компилируется в нечто вроде:

call .SomeFunction  ; calls to SomeFunction(), which stores its return value in eax
sub eax, 1 ; subtract 1 from eax and store in eax, set S (sign) flag if result is negative
jl ELSEBLOCK ; GOTO label "ELSEBLOCK" if S flag is set
call .foo ; this is the "if" black, call foo()
j FINISH ; GOTO FINISH; skip over the "else" block
ELSEBLOCK: ; label this location to the assembler
call .bar
FINISH: ; both paths end up here
ret ; return

Обратите внимание, что "bool" на самом деле нигде не сохраняется.

6
ответ дан 24 November 2019 в 08:43
поделиться

Вы практически не можете установить значение found. Отладка оптимизированных программ редко стоит хлопот, компилятор может переупорядочить код таким образом, чтобы он никоим образом не соответствовал исходному коду (кроме получения того же результата), тем самым беспредельно запутывая отладчиков.

4
ответ дан 24 November 2019 в 08:43
поделиться

При отладке оптимизированных программ (что может быть необходимо, если ошибка не обнаруживается в отладочных сборках), вам часто приходится понимать, что сгенерирован компилятором сборки.

В вашем конкретном случае return значение cpnd_find_exact_ckptinfo будет храниться в регистре, который используется на вашей платформе для возвращаемых значений. На ix86 это будет % eax . На x86_64 : % rax и т. Д. Возможно, вам придется поискать в Google «соглашение о вызове процедуры [ваш процессор]», если это не соответствует ни одному из вышеперечисленных.

Вы можете проверить этот регистр в GDB , и вы можете его установить. Например, на ix86 :

(gdb) p $eax
(gdb) set $eax = 0 
4
ответ дан 24 November 2019 в 08:43
поделиться

Перекомпилировать без оптимизации (-O0 в gcc).

74
ответ дан 24 November 2019 в 08:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: