GetSmart 0 5 марта, 2013 Опубликовано 5 марта, 2013 · Жалоба Непонятный баг в виде выпадения в HardFault из sprintf при выводе форматированного float, причём в некоторых случаях. Юзал эту версию ИАРа вместе со sprintf для LPC1768 и ни на какие грабли не попадал. Стек проверял, его достаточно, оптимизация никак не влияет. Простенький кастрированный проект прилагаю для LPC1114 (без кварца) можно потестить. Прочитал все исправленные баги в версии 6.30 и не нашёл ничего об исправленном sprintf. Хотя тот же код в 6.30 не зависает, но проверил наспех. Поэтому самому интересно в чём косяк и исправлен ли он в новых версиях ИАРа. sprintf((char *)&buf, "started\15\12"); sendBuf(&buf[0]); for (uInt i=0; i<sizeof(buf); ++i) buf[i] = 0xeb; float freq = 82.6046981; sprint_flag = 10; sprintf((char *)&buf, "freq1=%1.5f\15\12", freq); // <------- тут происходит падение на HardFault sprint_flag = 0; sendBuf(&buf[0]); sprintf((char *)&buf, "ended\15\12"); sendBuf(&buf[0]); Регистры на картинке взяты из режима исключения HardFault, на котором стоит бесконечный цикл. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 5 марта, 2013 Опубликовано 5 марта, 2013 · Жалоба Может, UNALIGN_TRP установлен? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 6 марта, 2013 Опубликовано 6 марта, 2013 (изменено) · Жалоба Это что такое и с чем его едят? Вообще-то я ничего с этой опцией не делал. Если по-умолчанию проц её держит в неправильном состоянии, то это ненормально. При выводе многих других значений float, например 0.0 всё работает отлично. ----------- Упд. Посмотрел в мануале на LPC111x. Регистр с этой опцией - RO, то бишь не меняется и бит этот всегда установлен. Изменено 6 марта, 2013 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба Это что такое и с чем его едят? Битик в Configuration Control Register, включающий abort при любом невыровненном доступе. По умолчанию выключен, разумеется. В дизассемблере криминала нет, кроме упомянутого доступа. Так что проверьте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба Если буфер (buf) является массивом, то char-указатель на него записывается так: (char *)buf а не так: (char *)&buf А если же автор программы хочет обязательно куда-то вставить значок &, то пусть пишет: (char *)&buf[0] и это будет правильно. Т.е. во всех функциях sprintf в качестве 1-го аргумента следует указывать (char *)buf или (char *)&buf[0], а не (char *)&buf А покуда это не сделано, искать какие-то иные ошибки в его коде неразумно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба Стоп, это ж M0, а он в принципе не умеет unaligned access делать. В опциях точно M0 стоит? Если да, тогда баг однозначно. Т.е. во всех функциях sprintf в качестве 1-го аргумента следует указывать (char *)buf или (char *)&buf[0], а не (char *)&buf А покуда это не сделано, искать какие-то иные ошибки в его коде неразумно. В случае массива buf и &buf - это одно и то же. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба В случае массива buf и &buf - это одно и то же. Только в тех случаях, когда массив статический, да и то взависимости от реализации компилятора. В случаях, когда массив выделяется динамически, вы не правы во всех отношениях. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба ОК, согласен. Но в данном конкретном случае это к проблеме ни малейшего отношения не имеет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ashr 0 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба Попробуйте так: sprintf((char *)buf, "freq1=%1.5f\15\12", (double)freq); Т.е. приведите аргумент freq к double. Да, и стек должен быть на 8 выровнен (по крайней мере для CM3 это обязательно). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба Стоп, это ж M0, а он в принципе не умеет unaligned access делать. В опциях точно M0 стоит? Если да, тогда баг однозначно. Да, точно М0. Мне во всём этом интересно, что баг этот зависит от стечения многих нюансов. Например формата %1.5 в сочетании с float. Поэтому и приводить к double смысла нет. Там с тем значением плавучки идёт округление двух чисел и результат сокращается до 4 знаков после запятой. Может это что-то значит. Вообще, хотелось бы выяснить задокументирован этот баг или нет. И связь с новыми версиями компиляторов. Почему, кстати, у многих местных модераторов есть такая привычка делать несущественные замечания. Зелтиго, Резидент, Ксюша, все страдают этим. Зелтиго в отсутствие аргументов вообще любит/л цепляться за while(1). Если конструктивно нечего сказать, то лучше промолчать. ИМХО это "болезнь", корелирующая с некой административной профнепригодностью. В том конкретном случае &buf и &buf[0] абсолютно одинаковый код дают, т.к. буфер статический с абсолютным адресом. Меняй, не меняй каша слаще не станет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ashr 0 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба Да, точно М0. Мне во всём этом интересно, что баг этот зависит от стечения многих нюансов. Например формата %1.5 в сочетании с float. Поэтому и приводить к double смысла нет. Почему, кстати, у многих местных модераторов есть такая привычка делать несущественные замечания. Зелтиго, Резидент, Ксюша, все страдают этим. Зелтиго в отсутствие аргументов вообще любит/л цепляться за while(1). Если конструктивно нечего сказать, то лучше промолчать. ИМХО это "болезнь", корелирующая с некой административной профнепригодностью. В том конкретном случае &buf и &buf[0] абсолютно одинаковый код дают, т.к. буфер статический с абсолютным адресом. Меняй, не меняй каша слаще не станет. Мдя. Зачем вы вообще совета просите, если не хотите хотя бы проверить его. Почитайте стандарт С. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 6 марта, 2013 Опубликовано 6 марта, 2013 (изменено) · Жалоба Стоп, это ж M0, а он в принципе не умеет unaligned access делать. Ну а допустим это был бы СМ3 со сброшенным битом UNALIGN_TRP. Он ведь всё-равно не так сохранил бы в память как умеет х86? То бишь прога не зависла бы, но значение неправильное бы выводила? Начинаю сомневаться за свои проекты, работающие в 5.40 для СМ3. Мдя. Зачем вы вообще совета просите, если не хотите хотя бы проверить его. Почитайте стандарт С. Прочитал. Исправил. Ничего не изменилось. Вам полегчало? Ведь это было изначально очевидно, что дело не в этом. Даже напрягаться не надо было на написание сообщений. К вам это не относится, но есть такая вещь: кто умеет - помогает, кто не умеет - цепляется. Уметь видеть нечёткое несоответствие стандарту, которое не влияет на кодогенерацию - гораздо полезнее, чем просто видеть несоответствие стандарту. Если дотошно разбирать первоначальный код, то он абсолютно верный по стандарту. Не универсальный, но верный в конкретном случае, учитывая рядом стоящее описание переменной buf. Доказывается это просто, вручную выполняя однозначный анализ компилятора. Поэтому даже отсылка в чтение стандарта является слишком безапеляционной. По поводу дабла - смысл не в том, чтобы как-нибудь обойти этот баг, а точно выяснить может ли он при каких-нибудь условиях и каких-нибудь параметрах функции появляться. Ну и конечно разобраться чей это баг. По поводу выравнивания на 8 "внутри кода" (ака перед вызовом sprintf) - это очень непонятная мне вещь. Зачем оно? То, что внутри скрипта линкера должно быть выравнивание на 8, это есть. Изменено 6 марта, 2013 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
shmur 0 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба А какая версия printf стоит в настройках проекта? Помню что small точно не работает с флоатом, то есть символ %f просто не раскручивается, но возможно в реализации либы для М0 там баг и все падает :) Попробуйте поставить full. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба Ну а допустим это был бы СМ3 со сброшенным битом UNALIGN_TRP. Он ведь всё-равно не так сохранил бы в память как умеет х86? То бишь прога не зависла бы, но значение неправильное бы выводила? Начинаю сомневаться за свои проекты, работающие в 5.40 для СМ3. Нет, M3 бы отработал правильно, сохранил "как x86". В отличие от M0 он умеет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 6 марта, 2013 Опубликовано 6 марта, 2013 · Жалоба Попробуйте поставить full. Такая и стоит. Иначе бы он вообще никакие значения плавучки не отображал. А он отображает, когда не виснет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться