Что не так, если оптимизация компилятора включена в отладочной сборке? - PullRequest
2 голосов
/ 19 января 2011

Почему необходимо / рекомендуется отключать все оптимизации компилятора при отладке приложения?

Фон

Я работаю в 8-битном микроконтроллере (OKI 411), который имеет 15 Кбайт полезной памяти для программ обработки прерываний + область / окно ПЗУ (глобальные переменные const) + код. Мы почти съели ~ 13K, поэтому очень заманчиво включить максимально возможную оптимизацию даже во время отладки.

Ответы [ 5 ]

6 голосов
/ 19 января 2011

При компиляции двоичного файла отладки компилятор пытается поддерживать соответствие 1: 1 между операторами кода (или частями операторов кода) инструкциям на языке ассемблера. Таким образом, когда вы отлаживаете, вы можете пошагово выполнять инструкции за инструкциями, и отладчику легко сопоставить свою текущую позицию в двоичном файле с правильным исходным кодом. Обычно компилятор также гарантирует, что все именованные переменные действительно существуют где-то в памяти, чтобы вы могли просматривать их содержимое в отладчике.

Оптимизация компилятора может исключить неиспользуемые или ненужные локальные переменные и может реструктурировать ваш код, чтобы он был более эффективным. Функции могут быть встроенными, а выражения могут быть частично или полностью предварительно вычислены или переставлены. Большинство из этих и подобных оптимизаций затрудняют корреляцию исходного исходного кода с созданной сборкой.

5 голосов
/ 19 января 2011

Рассмотрим:

for (i = 0; i < 10; i++) {
    src[i] = dest[i];
}

После оптимизации этот код может выглядеть следующим образом:

src[0] = dest[0];
src[1] = dest[1];
⋮
src[9] = dest[9];

Другими словами, i больше нет.Отладчик ожидал, что i будет находиться в кадре стека, но оптимизатор удалил его.

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

2 голосов
/ 20 января 2011

Я столкнулся с похожей ситуацией, когда я пытался прочитать из аппаратного регистра, регистр был отображен в память, и он дал мне неправильные значения с CFLAGS = "- o2" в gcc. Однако когда я включил CFLAGS ="-O0", он начал работать. Стоит упомянуть, что тот же результат может быть достигнут путем преобразования его в переменную volatile, так что оптимизация компилятора обойдена.

2 голосов
/ 19 января 2011

Это нормально, чтобы включить его. Обычно он отключен, потому что компиляция идет быстрее, что для больших проектов может быть реальной проблемой. На самом деле лучше включить его, если вы можете, чтобы не было неприятных проблем из-за оптимизации в последнюю минуту.

В вашем случае я бы обязательно включил его.

Это может вызвать проблемы с определенными формами отладки, но вы должны быть в состоянии отключить его в этих случаях.

1 голос
/ 19 января 2011

Единственное, о чем я могу думать, это то, что это может усложнить отладку.

Кроме этого, проблем быть не должно.

...