Настройки компилятора в Atmel Studio 6 и отладка на симуляторе - грабли

Интересная, но, в общем, неудивительная вещь при отладке — возможно, кому-то пригодится.

Заметил, что при пошаговом выполнении программы оказываюсь в той функции, которая в этот момент (да и вообще в данной конфигурации программы) не вызывается. Причем оказываюсь не в начале функции, а где-то в середине. Заинтересовался — какого, собственно?

Настройки компилятора (оптимизация) были следующие:
— уровень оптимизации -O2
— галки стояли на «Pack structure members together (-fpack-struct)» и «Prepare functions for garbage collection (-ffunction-sections)»

Попробовал поиграться с уровнями оптимизации — без толку. Выключаю -ffunction-sections — всё нормально. А жаба душит, включение этой опции даёт уменьшение размера почти в два раза.

В хелпе написано следующее:
"-ffunction-sections: Prepare functions for garbage collection, if a function is never used, its memory will be scrapped"
То бишь, если функция нигде не используется, то под неё вроде бы память не выделяется. Оно и логично, сборка мусора и все такое.

То, что меня удивило: при включенной опции — при попадании программы в середину нигде не использующейся функции выхожу я из неё буквально на следующем шаге и туда, куда мне и надо. Посмотрел окно «disassembly» — там, куда я попадаю, Сишный текст строчки из НЕИСПОЛЬЗУЕМОЙ функции есть, а ассемблерные инструкции все как надо (там идет сброс флага и выход из ИСПОЛЬЗУЕМОЙ функции, в которую я заходил и как раз должен из неё выйти) Что за ерунда — так и не понял, может, кто точно знает и расскажет? В железе пока не пробовал, но судя по ассемблерному тексту, все должно работать правильно.

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

Да, чуть не забыл, при использовании -ffunction-sections в опциях линкера должно быть включено «Garbage collect unused sections (-Wl--gc-sections)», а то толку от использования -ffunction-sections не будет.

Для интересующихся, про настройки компилятора и линкера: Optimisations of AVR programs using avr-gcc
  • 0
  • 15 июня 2012, 10:20
  • madmazy

Комментарии (15)

RSS свернуть / развернуть
А внимательней посмотреть? Скорей всего оптимизатор решил приколоться и обьединил куски кода, а логика не порушилась. А если O0 поставить та же фигня?
0
у меня похожие глюки вылазят в кейле и вроде в симуляторе четвертой студии тоже. Я как-то решил, что это глюк визуализации отладки, потому как дизассемблер показывает, что все правильно исполняется. Особенно любит отладчик скакать по инструкциям циклов, из-за этого иногда сложно определить сколько проходов реально прошло, приходится открывать окно переменных и смотреть.
0
В четвертой я тоже с таким сталкивался, и в итоге забил, т.к. дизассемблер и железо работали нормально. Видимо, это удачно переехавший глюк…
0
При нулевом уровне оптимизации картина примерно такая же, если на сишный текст смотреть, с ассемблерным сильно подробно не разбирался…
0
В CooCox таже фигня при отладке и это нормально — если используешь -O1,-O2 то при отладке среда «промахивается» и курсор ставиться нифига не туда где должно быть исполнение, но это не сильно мешает т.к. можно догадаться
0
Интересно, а почему она промахивается? Я сейчас попробовал — при выключенной оптимизации например даже {} как и должно быть считаются оператором и туда ставится курсор, а стоит включить оптимизацию и уже хренушки.
0
Похоже на косяки генерации debug info. Либо дебаг-инфо считает что функции не были почиканы линкером.
Алсо, это же надо додуматься обычный смартлинк так назвать. Ну и реализовано оно через задницу, отсюда и глюки. Последствия использования устаревшего формата объектников, в которых не предусмотрена возможность хранения нужной метаинформации.
Поковыряй настройки генерации дебажной инфы. А то мож ты вообще в релизе собирашь, с выключенной дебаг-инфо и оно использует старую случайно сгенеренную в дебаг-конфигурации.
0
  • avatar
  • Vga
  • 15 июня 2012, 13:06
Собираю в дебаге с максимальным уровнем дебаг-инфо (-g3). А что есть смартлинк?
0
Смартлинк — выкидывание неиспользуемых функций, переменных и всего такого при линковке. Из-за излишне глубокого разделения этапов компиляции и линковки в С реализация ее затруднена. По крайней мере основанные на BinUtils компиляторы реализуют умную линковку через задницу — создавая по секции на функцию, а то и по объектнику на функцию, из-за ограничений BinUtils и его формата объектников. Особо страшно это выглядит в паскале — он рассчитан на модульную компиляцию и прикручивание его к binutils выглядит как лес костылей.
0
сейчас глянул, да, почти по секции на функцию получается
по объектнику на функцию это конечно вообще жесть.
спасибо за инфу.
0
По идее должно быть не почти, а ровно.
0
оно наверное ровно и есть, просто функций до фига, считать лень:)
0
по объектнику на функцию это конечно вообще жесть.
Из-за этого FPC компилирует чуть ли не медленнее, чем С++. Тогда как Delphi компилирует порядка 50к строк в секунду — термин ночной сборки к нему даже не применим, т.к. даже самые большие проекты собираются за считанные минуты.
0
проблема в том, что оптимизируя осемблерную составляющую, сишный вид остаецца тем же, потому как не крути но прямой связи между пошаговой трасировкой по дизасму и аналогичного отображения по сорцу добицца не выйдет
0
оно может и так, но залезание в другую функцию, не имеющую отношения к вызываемой — все равно жесть.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.