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

 
 
 
Reply to this topicStart new topic
> Ошибка при копировании структур, Почему-то виснет при копировании вложенных структур
kolobochishe
сообщение Oct 20 2014, 10:41
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634



Структура типа im_rect является вложенной в структуре im_widget. При создании массива из элементов im_widget внутренняя структура im_rect InnerRect не копируется (прибор виснет при отладке) в случае если элементы im_widget в одном массиве. В Visual Studio все работает, а в Visual DSP виснет. Что делать? И как Вы делаете копирование структур? Читал, что в старых компиляторах на это было ограничение. Можно memcpy или memmove. Но хочется разобраться в таком поведении контроллера.

Код
typedef int_fast16_t im_int;

typedef struct
{
im_int Left;
im_int Top;
im_int Right;
im_int Bottom;
} im_rect;

typedef struct {
im_int Type;
im_rect OuterRect;    
im_rect InnerRect;    
void * Widget;
im_int State;
char * Title;
char * Text;
char * Hint;
pt2Function Function;
void * AddInf;
im_pixel BkPixel;
uchar AutoSize;
pt2Function DrawFunction;
} im_widget;


im_rect TestRect = { 5, 6, 7, 8 };
im_widget wFKey[4];

wFKey[0].InnerRect.Left = 5;

memcpy(&wFKey[1].InnerRect, &wFKey[0].InnerRect, sizeof(im_rect)); // Работает
wFKey[1].InnerRect = wFKey[0].InnerRect; // Виснет
wFKey[1].InnerRect = TestRect; // Работает


Т.е. виснет при копировании вложенных структур внутри массива.
Go to the top of the page
 
+Quote Post
WitFed
сообщение Oct 20 2014, 13:07
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 271
Регистрация: 6-12-11
Из: Taganrog
Пользователь №: 68 701



Думаю, надо точно убедиться в проблеме в дизассемблере при выполнении по одной команде и слать минимальный пример разработчику, пусть разбирается. Если будут дополнительные замечания и наблюдения, что идёт не так, они ещё и поощрить могут.
Раз у Студии от MS вопросов нет, пусть остальные подтягиваются wink.gif
Если С++ допустим, можно на его коде то же самое попробовать. Если будет падать -- ссылки на структуру заюзать. Всё же некрасиво наблюдать memcpy() в обменах структурированными данными.
Go to the top of the page
 
+Quote Post
_pv
сообщение Oct 20 2014, 13:25
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



а что там с #pragma pack, #pragma align и реальным размером im_int?
Go to the top of the page
 
+Quote Post
kolobochishe
сообщение Oct 20 2014, 14:07
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634



Цитата(_pv @ Oct 20 2014, 18:25) *
а что там с #pragma pack, #pragma align и реальным размером im_int?


Никак. Ничего принудительно не ставил. Проверил на другой тестовой структуре с таким же полем, но поменьше - все работает. С включенной оптимизацией кода тоже все работает.

Вот дисассемблер нерабочего кода

Красный брекпойн - начало копирования структур. Потом выделен последняя "рабочая" команда. Дальше программа уходит в какое-то исключение

Сообщение отредактировал kolobochishe - Oct 20 2014, 14:08
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
_pv
сообщение Oct 20 2014, 15:44
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



судя по P1.L = 0x8f1E, последующим за этим P1 += 4; и попытке достать потом по адресу 0x8f22 32х разрядное число, исключение в которое дальше всё уходит - misaligned access.
Go to the top of the page
 
+Quote Post
kolobochishe
сообщение Oct 21 2014, 05:41
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634



Цитата(_pv @ Oct 20 2014, 21:44) *
судя по P1.L = 0x8f1E, последующим за этим P1 += 4; и попытке достать потом по адресу 0x8f22 32х разрядное число, исключение в которое дальше всё уходит - misaligned access.


А как Вы определили, что это именно "невыровненный доступ"?
Go to the top of the page
 
+Quote Post
_pv
сообщение Oct 21 2014, 07:41
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



P1=0x8f22 на 4 не делится, и R0 = [P1++] пытается достать 32х разрядные данные.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Oct 21 2014, 18:41
Сообщение #8


Гуру
******

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



А вы попробуйте без typedef:
Код
struct im_rect { im_int Left; im_int Top; im_int Right; im_int Bottom; };

struct im_widget {
  im_int Type;
  struct im_rect OuterRect;    
  struct im_rect InnerRect;
  .....
} wFKey[4];

Может, компилятору так больше понравится?
Я сама всегда так пишу, а без typedef только однажды обойтись не смогла.
Go to the top of the page
 
+Quote Post
inventor
сообщение Oct 31 2014, 10:10
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



Цитата(kolobochishe @ Oct 20 2014, 14:41) *
Структура типа im_rect является вложенной в структуре im_widget.


на вскидку: невыровненная структура - вероятно в эксепшен вылетает
смотрите чтобы все поля по 32 бита были.
ну а если нет такой возможности - делайте юнион
на свою структуру и копируйте с помощью memcpy по-байтно

Не надо цитировать всё подряд.

Сообщение отредактировал Herz - Oct 31 2014, 15:32
Причина редактирования: Избыточное цитирование
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 31 2014, 12:56
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(inventor @ Oct 31 2014, 12:10) *
на_вскидку: невыровненная структура - вероятно в эксепшен вылетает
Автор пишет, что никаких специальных мер по нарушению выравнивания не предпринимал, читайте внимательнее.

Цитата(inventor @ Oct 31 2014, 12:10) *
смотрите чтобы все поля по 32 бита были.
А это еще зачем? А вложенная стрктура тоже полем является, она тоже по 32 бита должна быть?

Цитата(inventor @ Oct 31 2014, 12:10) *
ну а если нет такой возможности - делайте юнион на свою структуру и копируйте с помощью memcpy по-байтно
1) у memcpy параметр имеет тип void *, согласно правилам неявного приведения типов указатель на структуру будет приведен к этому типу неявно. Никакой union не нужен.
2) Стандарт языка гарантирует, что структура должна копироваться без всяких плясок с бубном. Вне зависимости от размера, типа и количества своих членов. Даже если структура объявлена с другим выравниванием, компилятор об этом знает и обязан выполнять копирование корректно. Проблема с выравниванием может возникнуть только при доступе через указатель, если программист явным приведением типов сознательно нарушил правила выравнивания.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
_pv
сообщение Nov 1 2014, 08:35
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(Сергей Борщ @ Oct 31 2014, 18:56) *
Автор пишет, что никаких специальных мер по нарушению выравнивания не предпринимал, читайте внимательнее.

Даже если структура объявлена с другим выравниванием, компилятор об этом знает и обязан выполнять копирование корректно.

он хоть и обязан, но баги в компиляторах тоже бывают, и про VDSP нельзя сказать что это самый безглючный компилятор.
тут похоже грабли из-за массива структур, посмотрите по каким именно адресам он от положил wFKey[0] и wFKey[1].
и для проверки, попробуйте добавить, сколько надо ucharов в структуру, чтобы размер sizeof(im_widget) стал кратным четырём.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 1 2014, 10:26
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(_pv @ Nov 1 2014, 10:35) *
попробуйте добавить, сколько надо ucharов в структуру, чтобы размер sizeof(im_widget) стал кратным четырём.
Вот если размер im_widget окажется не равен четырем - это, действительно, будет бага компилятора. Потому что размер структуры по стандарту кратен наибольшему выравниванию ее членов. В структуре есть указатели, выравнивание указателя в VDSP, насколько понимаю, равно четырем - компилятор обязан размер структуры сделать кратным четырем. Очень сомневаюсь, что такую ошибку пропустили бы.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 08:51
Рейтинг@Mail.ru


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