2015-02-12 3 views
2

Я пытаюсь диагностировать проблему. Проблема в том, что моя программа отлично работает, если я помещаю printf (в частности printf) в начало программы, и это не так, если я этого не делаю. Эта проблема очень специфична для цикла, который считывает переменную systick, которую я увеличиваю в systick_handler.ARM, .COMMON раздел и -fno-общий флаг

Если я, однако, компилирую с -fno-common, тогда все работает. Почему это поведение?

Кроме того, я удалил разделы .COMMON из моего сценария компоновщика, потому что они делают программу почти вдвое большей. Все так хорошо работает без них, но я подозреваю, что их отсутствие каким-то образом вызывало бесконечный цикл, когда я компилировался со стандартным (-fcommon) флагом. Тем не менее я не вижу ссылки на раздел .COMMON в моих файлах. Это должно быть просто из libc.

Может ли кто-нибудь объяснить, что происходит?

+0

http://sscce.org/ – auselen

+0

Я не могу представить один, потому что я не совсем уверен, что проблема заключается в первое место. Я думаю, что это где-то внутри libc, потому что я вообще не использую разделы .common. Я решил его, скомпилировав с -fno-common только потому, что я вообще исключил разделы .common. Но я не уверен, что это может привести к некоторым неизвестным проблемам в будущем или если -fno-common решило проблему навсегда. К сожалению, у меня нет доступа к интерфейсу аппаратной отладки на платформе, где проблема возникает. – Martin

+0

Создайте файл карты и посмотрите, что находится в '.COMMON'. –

ответ

5

Когда вы используете -fno-common, глобальные переменные неинициализируются в разделе .bss (о, хотя руководство говорит данные) GCC. Если вы не используете эту опцию, они помещаются в специальный раздел COMMON.

Если вы опустите этот раздел из сценария компоновщика, компоновщик просто помещает его в ОЗУ, возможно, перекрываясь с другими данными. Вы можете проверить его в файле карты. Я просто попробовал это со своим сценарием компоновщика и обнаружил, что содержимое COMMON было помещено в ту же область памяти, что и куча в моем случае. Это означает, что глобальные переменные и все, что выделяется, например, malloc, перезаписывают друг друга. Не делай этого. Плохие вещи произойдут.

Что касается безопасности использования -fno-common и игнорирования COMMON: Я предполагаю, что библиотеки также могут содержать COMMON. Даже если ваш код не содержит этот раздел, потому что вы используете -fno-common, это не означает, что компоновщику не нужно его обрабатывать. Просто добавьте * (ОБЩИЙ) рядом с вашим * (. Bss), и вы в безопасности. Если потребление памяти увеличивается, у него есть веская причина.

Дальнейшие показания:

+0

Я не уверен, что я наблюдал, но Valgrind зажигает свечу, когда пытается протестировать на платформах Apple. Apple либо (1) помещает некоторые инициализированные глобальные общие черты, либо (2) выполняет ленивую инициализацию в секции, в которой они находятся. Единственный способ, которым я мог остановить выводы Valgrind, заключался в том, чтобы добавить '__attribute __ ((раздел (« nocommon »))) 'по переменным задачи. Вероятно, мы должны добавить '-fno-common' в командную строку. – jww

Смежные вопросы