Jump to content
Форум по продукции MOXA

W406-LX ключи оптимизации arm-linux-gcc и Segmentation fault


Recommended Posts

Здравствуйте!

 

Обнаружил проблему с компилятором, входящим в состав тул-чейна для W406-LX.

При указании компилятору ключей оптимизации -O, -O2, -O3, -Os работяющая ранее без оптимизации программа начинает падать с ошибкой Segmentation fault. Насколько мне хватило мозгов ковыряться в отладчике, я обнаружил, что проблема находится где-то в районе преобразования типа long long int в double. Я не силен в асемблере, тем более в arm-асемблере, но есть подозрение, что внутренняя функция, которую подставляет компилятор в месте такого преобразования типов, портит стек.

При этом без указания ключей оптимизации все работает без вопросов, в т.ч. этот же исходник спокойно компилируется и работает на PC под дебианом и под виндой в режиме x86 и x64, как с оптимизацией, так и без.

Без оптимизаци эксплуатировать программу мне как-то совесть не позволяет, ведь оптимизация дает существенное увеличение быстродействия.

Прошу комментариев компетентных людей...

Link to comment

Здравствуйте!

 

Можете ли Вы написать минимальную демонстрационную программу, на которой можно увидеть указанную проблему?

Также, сообщите, пожалуйста, версию тулчейна.

Link to comment

Программа:

#include <stdio.h>
int k;
int main(void)
{
  long long int i;
  double d;

  for(k=0; k<100000000; k++) {
     i = k+1;
     d = i;
     if(k%4000000 == 0)
     printf("%d\n", k);
  }
  return 0;
}

 

Проблему вызывает строка d = i;

На этом месте компилятор вставляет вызов функции __floatdidf. Видимо, она гробит стек.

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

В частности эта программа с опциями оптимизации -O2 или -O3 работает корректно.

А без оптимизации падает на 169 обороте цикла.

Про загубленный стек косвенно говорит внесение строчки int k; внутрь функции main - чудеса при выполнении возникают другие.

 

Пока нашел временный выход - написал свои функции преобразования long long в double и обратно. Но это криво.

 

Версию тул-чейна не знаю где посмотреть. arm-linux-gcc выдает 4.2.1

Если верить сайту moxa.com, то тул-чейн последний, т.к. скачивал я его где-то на границе 12-13 годов...

Link to comment

Расследование показало, что в процессоре EP9302, на котором основан W406, применён нестандартный блок операций с плавающей запятой, который не поддерживается в gcc. Если использование аппаратной обработки плавающих чисел не критично, то наиболее оптимальным вариантом решения будет добавить ключ -msoft-float. Это заставит компилятор использовать программную обработку чисел с плавающей запятой.

Link to comment

Прекрасно, только это не работает.

Первая попытка откомпилировать программу показала что:

/usr/local/arm-linux/lib/gcc/arm-linux/4.2.1/../../../../arm-linux/bin/ld: ERROR: /usr/local/arm-linux/lib/gcc/arm-linux/4.2.1/../../../../arm-linux/lib/libsms.so uses hardware FP, whereas smstest uses software FP

Думаю, понятно о чем речь...

 

P.S. Интересно, я первый это заметил?

Link to comment

Да, судя по всему, libsms в тулчейне собран только под hard-float little-endian. Попробуйте подменить файл libsms.so на этот. Также, можно использовать версию для статической компиляции.

 

Заметить данную проблему Вы вполне могли первым, т.к. W406 редко используют для задач, в которых требуются вычисления с плавающей запятой.

Link to comment

Там проблема еще с кучей библиотек...

 

Вообще на доработку gcc можно надеяться?

Тем более, там большая часть хардверных операций с плавающей точкой компилируется сейчас нормально,

нужно лишь немного допилить...

 

Или начинать искать другое устройство? :-)

Link to comment

Проблемы с библиотеками из стандартной поставки или сторонними?

 

Доработка, скорее всего, возможна, т.к. патчи от сторонних разработчиков в интернете есть. Ждём, что нам ответит производитель устройства.

Link to comment

Проблемы с библиотеками из стандартной поставки или сторонними?

Из стандартной поставки.

Вроде разобрался. Нужно не использовать опцию -msoft-float, а использовать другое имя компилятора: armsf-linux-gcc. Тогда и генерируется программный код для оперций с плавающей точкой. Но с этим тоже проблемы при проверке. Например X*Y не равно Y*X или sqrt(X*X) не равно X. И зачем такое счастье? Пока заменил операцию, вызывающую проблемы на "полусофтверное" решение. Других проблем пока не выявлено. Посмотрю, что будет дальше...

 

Доработка, скорее всего, возможна, т.к. патчи от сторонних разработчиков в интернете есть. Ждём, что нам ответит производитель устройства.

Очень хочется положительного решения...

 

P.S. что-то с часами на форуме - отправляю письмо в 16:50, на форуме написано 17:10 (грубо).

Link to comment
  • 3 weeks later...
  • 2 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...