реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> IAR 5.40.0.51500 баг в sprintf @ lpc1114/CM0
GetSmart
сообщение Mar 5 2013, 23:49
Сообщение #1


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Непонятный баг в виде выпадения в 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, на котором стоит бесконечный цикл.
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
Прикрепленное изображение
 


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 5 2013, 23:59
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Может, UNALIGN_TRP установлен?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 6 2013, 00:05
Сообщение #3


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Это что такое и с чем его едят?
Вообще-то я ничего с этой опцией не делал. Если по-умолчанию проц её держит в неправильном состоянии, то это ненормально. При выводе многих других значений float, например 0.0 всё работает отлично.

-----------

Упд.
Посмотрел в мануале на LPC111x. Регистр с этой опцией - RO, то бишь не меняется и бит этот всегда установлен.

Сообщение отредактировал GetSmart - Mar 6 2013, 00:11


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 6 2013, 00:18
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(GetSmart @ Mar 6 2013, 04:05) *
Это что такое и с чем его едят?

Битик в Configuration Control Register, включающий abort при любом невыровненном доступе.
По умолчанию выключен, разумеется. В дизассемблере криминала нет, кроме упомянутого доступа.
Так что проверьте.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Mar 6 2013, 00:18
Сообщение #5


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Если буфер (buf) является массивом, то char-указатель на него записывается так:
(char *)buf
а не так:
(char *)&buf

А если же автор программы хочет обязательно куда-то вставить значок &, то пусть пишет:
(char *)&buf[0]
и это будет правильно.

Т.е. во всех функциях sprintf в качестве 1-го аргумента следует указывать (char *)buf или (char *)&buf[0], а не (char *)&buf
А покуда это не сделано, искать какие-то иные ошибки в его коде неразумно.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 6 2013, 00:27
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Стоп, это ж M0, а он в принципе не умеет unaligned access делать.
В опциях точно M0 стоит? Если да, тогда баг однозначно.

Цитата(Xenia @ Mar 6 2013, 04:18) *
Т.е. во всех функциях sprintf в качестве 1-го аргумента следует указывать (char *)buf или (char *)&buf[0], а не (char *)&buf
А покуда это не сделано, искать какие-то иные ошибки в его коде неразумно.

В случае массива buf и &buf - это одно и то же.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Mar 6 2013, 00:30
Сообщение #7


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(aaarrr @ Mar 6 2013, 04:27) *
В случае массива buf и &buf - это одно и то же.


Только в тех случаях, когда массив статический, да и то взависимости от реализации компилятора. В случаях, когда массив выделяется динамически, вы не правы во всех отношениях.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 6 2013, 01:23
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



ОК, согласен. Но в данном конкретном случае это к проблеме ни малейшего отношения не имеет.
Go to the top of the page
 
+Quote Post
shreck
сообщение Mar 6 2013, 01:43
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 327
Регистрация: 24-06-06
Из: Томск
Пользователь №: 18 328



Попробуйте так:
Код
sprintf((char *)buf, "freq1=%1.5f\15\12", (double)freq);

Т.е. приведите аргумент freq к double.
Да, и стек должен быть на 8 выровнен (по крайней мере для CM3 это обязательно).
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 6 2013, 02:02
Сообщение #10


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(aaarrr @ Mar 6 2013, 06:27) *
Стоп, это ж M0, а он в принципе не умеет unaligned access делать.
В опциях точно M0 стоит? Если да, тогда баг однозначно.

Да, точно М0.
Мне во всём этом интересно, что баг этот зависит от стечения многих нюансов. Например формата %1.5 в сочетании с float. Поэтому и приводить к double смысла нет. Там с тем значением плавучки идёт округление двух чисел и результат сокращается до 4 знаков после запятой. Может это что-то значит. Вообще, хотелось бы выяснить задокументирован этот баг или нет. И связь с новыми версиями компиляторов.

Почему, кстати, у многих местных модераторов есть такая привычка делать несущественные замечания. Зелтиго, Резидент, Ксюша, все страдают этим. Зелтиго в отсутствие аргументов вообще любит/л цепляться за while(1). Если конструктивно нечего сказать, то лучше промолчать. ИМХО это "болезнь", корелирующая с некой административной профнепригодностью.

В том конкретном случае &buf и &buf[0] абсолютно одинаковый код дают, т.к. буфер статический с абсолютным адресом. Меняй, не меняй каша слаще не станет.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
shreck
сообщение Mar 6 2013, 02:33
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 327
Регистрация: 24-06-06
Из: Томск
Пользователь №: 18 328



Цитата(GetSmart @ Mar 6 2013, 09:02) *
Да, точно М0.
Мне во всём этом интересно, что баг этот зависит от стечения многих нюансов. Например формата %1.5 в сочетании с float. Поэтому и приводить к double смысла нет.

Почему, кстати, у многих местных модераторов есть такая привычка делать несущественные замечания. Зелтиго, Резидент, Ксюша, все страдают этим. Зелтиго в отсутствие аргументов вообще любит/л цепляться за while(1). Если конструктивно нечего сказать, то лучше промолчать. ИМХО это "болезнь", корелирующая с некой административной профнепригодностью.

В том конкретном случае &buf и &buf[0] абсолютно одинаковый код дают, т.к. буфер статический с абсолютным адресом. Меняй, не меняй каша слаще не станет.

Мдя.
Зачем вы вообще совета просите, если не хотите хотя бы проверить его.
Почитайте стандарт С.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 6 2013, 02:36
Сообщение #12


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(aaarrr @ Mar 6 2013, 06:27) *
Стоп, это ж M0, а он в принципе не умеет unaligned access делать.

Ну а допустим это был бы СМ3 со сброшенным битом UNALIGN_TRP. Он ведь всё-равно не так сохранил бы в память как умеет х86? То бишь прога не зависла бы, но значение неправильное бы выводила? Начинаю сомневаться за свои проекты, работающие в 5.40 для СМ3.

Цитата(shreck @ Mar 6 2013, 08:33) *
Мдя.
Зачем вы вообще совета просите, если не хотите хотя бы проверить его.
Почитайте стандарт С.

Прочитал. Исправил. Ничего не изменилось. Вам полегчало? Ведь это было изначально очевидно, что дело не в этом. Даже напрягаться не надо было на написание сообщений. К вам это не относится, но есть такая вещь: кто умеет - помогает, кто не умеет - цепляется. Уметь видеть нечёткое несоответствие стандарту, которое не влияет на кодогенерацию - гораздо полезнее, чем просто видеть несоответствие стандарту. Если дотошно разбирать первоначальный код, то он абсолютно верный по стандарту. Не универсальный, но верный в конкретном случае, учитывая рядом стоящее описание переменной buf. Доказывается это просто, вручную выполняя однозначный анализ компилятора. Поэтому даже отсылка в чтение стандарта является слишком безапеляционной. По поводу дабла - смысл не в том, чтобы как-нибудь обойти этот баг, а точно выяснить может ли он при каких-нибудь условиях и каких-нибудь параметрах функции появляться. Ну и конечно разобраться чей это баг.

По поводу выравнивания на 8 "внутри кода" (ака перед вызовом sprintf) - это очень непонятная мне вещь. Зачем оно? То, что внутри скрипта линкера должно быть выравнивание на 8, это есть.

Сообщение отредактировал GetSmart - Mar 6 2013, 03:37


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
shmur
сообщение Mar 6 2013, 05:35
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 28-11-11
Пользователь №: 68 553



А какая версия printf стоит в настройках проекта? Помню что small точно не работает с флоатом, то есть символ %f просто не раскручивается, но возможно в реализации либы для М0 там баг и все падает sm.gif Попробуйте поставить full.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 6 2013, 09:36
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(GetSmart @ Mar 6 2013, 06:36) *
Ну а допустим это был бы СМ3 со сброшенным битом UNALIGN_TRP. Он ведь всё-равно не так сохранил бы в память как умеет х86? То бишь прога не зависла бы, но значение неправильное бы выводила? Начинаю сомневаться за свои проекты, работающие в 5.40 для СМ3.

Нет, M3 бы отработал правильно, сохранил "как x86". В отличие от M0 он умеет.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 6 2013, 12:54
Сообщение #15


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(shmur @ Mar 6 2013, 11:35) *
Попробуйте поставить full.

Такая и стоит. Иначе бы он вообще никакие значения плавучки не отображал. А он отображает, когда не виснет.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 07:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.03345 секунд с 7
ELECTRONIX ©2004-2016