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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Неожиданное обнуление семафора, Указатель семафора сам по себе становится NULL
turnon
сообщение Sep 29 2015, 12:01
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Использую рекурсивный семафор. Иногда (1-2 раза в неделю при работе 7*24) указатель семафора становится NULL сам по себе.
Определяю это срабатыванием ассерта, FreeRTOS\Source\queue.c, line 491.

FreeRTOS V8.2.2, IAR.

Не пойму, что может такого происходить, что приводит к обнуления переменной ассерта?
Переполнение стека? Это контролируется vApplicationStackOverflowHook и vApplicationMallocFailedHook.
И от HighWaterMark до конца стека еще больше 20%.

Создание семафора:

_semaphore = xSemaphoreCreateRecursiveMutex();
assert(_semaphore != NULL);

_semaphore объявлена volatile.

Использование семафора:

assert(xSemaphoreTakeRecursive(_semaphore, (portTickType)portMAX_DELAY) == pdTRUE);
...
assert(xSemaphoreGiveRecursive(_semaphore) == pdTRUE);

Или так:

assert(xSemaphoreTakeRecursive(_semaphore, (portTickType)portMAX_DELAY) == pdTRUE);
...
assert(xSemaphoreTakeRecursive(_semaphore, (portTickType)portMAX_DELAY) == pdTRUE);
...
assert(xSemaphoreGiveRecursive(_semaphore) == pdTRUE);
...
assert(xSemaphoreGiveRecursive(_semaphore) == pdTRUE);

Прикрепленное изображение


Прикрепленное изображение
Go to the top of the page
 
+Quote Post
den_po
сообщение Sep 29 2015, 12:14
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(turnon @ Sep 29 2015, 16:01) *
Использование семафора:

assert(xSemaphoreTakeRecursive(_semaphore, (portTickType)portMAX_DELAY) == pdTRUE);

про обнуление не скажу, а вот вызовы функций в ассерты заворачивать нельзя
Go to the top of the page
 
+Quote Post
turnon
сообщение Sep 29 2015, 12:16
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Цитата(den_po @ Sep 29 2015, 15:14) *
а вот вызовы функций в ассерты заворачивать нельзя

Почему?
Go to the top of the page
 
+Quote Post
den_po
сообщение Sep 29 2015, 12:26
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Потому что assert это макрос, который в релизных конфигурациях обычно разворачивается в "ничто", то есть содержимое скобок в релизе просто игнорируется.
Go to the top of the page
 
+Quote Post
turnon
сообщение Sep 29 2015, 14:25
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Цитата(den_po @ Sep 29 2015, 15:26) *
Потому что assert это макрос, который в релизных конфигурациях обычно разворачивается в "ничто", то есть содержимое скобок в релизе просто игнорируется.

Ну как бы я знаю что у меня в assert, и assert - это уже мой вариант, по умолчанию идет макрос с именем assert_param. И даже по умолчанию там есть реализация - бесконечный цикл.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 29 2015, 15:16
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (turnon @ Sep 29 2015, 15:01) *
Переполнение стека? Это контролируется vApplicationStackOverflowHook и vApplicationMallocFailedHook.
И от HighWaterMark до конца стека еще больше 20%.

Кроме стеков задач есть еще и другие стеки. Но поскольку Вы жалуетесть только на одну переменную, хотя рядом с ней еще и явно другие находятся, а также то, что в результате всяких Ваших отладочных действий положение этой переменной в памяти скорее всего менялось, то представляется невероятным, что каким-то невообразимым способом забивается именно эта одна переменная и именно нулем, где-бы она в памяти не находилась. Посему, хотите верьте, хотите нет, но затираете Вы явным образом сами. Ну или не совсем явным. Смотрите, например, на какой-нибудь массив расположенный рядом с этой переменной.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
turnon
сообщение Sep 29 2015, 15:46
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Цитата(zltigo @ Sep 29 2015, 18:16) *
Посему, хотите верьте, хотите нет, но затираете Вы явным образом сами. Ну или не совсем явным. Смотрите, например, на какой-нибудь массив расположенный рядом с этой переменной.

Спасибо, уже по теме. А как понять что рядом?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 29 2015, 15:47
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (turnon @ Sep 29 2015, 18:46) *
Спасибо, уже по теме. А как понять что рядом?

MAP файл линкера.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
megajohn
сообщение Sep 29 2015, 16:17
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



Цитата(turnon @ Sep 29 2015, 18:46) *
Спасибо, уже по теме. А как понять что рядом?


можно через JTAG поставить DataBreakpoint и не париться


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 29 2015, 16:24
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (megajohn @ Sep 29 2015, 19:17) *
можно через JTAG поставить DataBreakpoint и не париться

Я бы не характеризовал словами "не париться" подключение где-нибудь на объекте в городе мухосранске царевопропойской губернии к JTAG (если он есть), отладчика, компьютера, установки софтины, обучение персонала и недельное ожидание события sad.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
turnon
сообщение Sep 29 2015, 16:37
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Цитата(zltigo @ Sep 29 2015, 18:47) *
MAP файл.

Уж простите за безграмотность. Что-то не нахожу в map файле полей объекта. Вот в Log есть поле _semaphore, а в map файле _semaphore не нахожу, как и остальных полей объекта.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 29 2015, 18:08
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (turnon @ Sep 29 2015, 19:37) *
Что-то не нахожу в map файле полей объекта. Вот в Log есть поле _semaphore, а в map файле _semaphore не нахожу, как и остальных полей объекта.

Мне трудно понять то, что Вы пишите sad.gif. Я не знаю, что такое Вы назвали "Log" и "поле объекта". Если _semaphore элемент структуры, то в map будет адрес и размер структуры.
Выложите map файл - посмотрю.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
turnon
сообщение Sep 30 2015, 08:50
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Цитата(zltigo @ Sep 29 2015, 21:08) *
Мне трудно понять то, что Вы пишите sad.gif. Я не знаю, что такое Вы назвали "Log" и "поле объекта". Если _semaphore элемент структуры, то в map будет адрес и размер структуры.
Выложите map файл - посмотрю.

Вот для примера сделал минимальный проект в IAR (пристегнутый zip). empty\tmp\Debug\List\Project.map.
В объекте gLog есть поле _inited и _fileSpec, а в map-файле этих полей в явном виде нет. Почему?
Прикрепленный файл  empty.zip ( 21.63 килобайт ) Кол-во скачиваний: 50


Сообщение отредактировал turnon - Sep 30 2015, 10:46
Go to the top of the page
 
+Quote Post
den_po
сообщение Sep 30 2015, 09:46
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(turnon @ Sep 29 2015, 18:25) *
Ну как бы я знаю что у меня в assert, и assert - это уже мой вариант, по умолчанию идет макрос с именем assert_param. И даже по умолчанию там есть реализация - бесконечный цикл.

Если речь об исходниках FreeRTOS, то там используется макрос configASSERT, и именно по умолчанию там реализация - "ничего".
FreeRTOS\Source\include\FreeRTOS.h:
Код
#ifndef configASSERT
    #define configASSERT( x )
    #define configASSERT_DEFINED 0
#else
    #define configASSERT_DEFINED 1
#endif

Да, исправляюсь, в assert и подобные макросы заворачивают вызовы функций, но только те, удаление которых не влияет на ход работы программы. Это точно не ваш случай. В вашем случае нужно сохранять результат вызова в переменные и в ассертах использовать именно их.
Попробуйте скомпилировать ваш проект в релизной конфигурации (с объявленным в настройках препроцессора макросом NDEBUG) и убедитесь.
Go to the top of the page
 
+Quote Post
turnon
сообщение Sep 30 2015, 10:44
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Цитата(den_po @ Sep 30 2015, 12:46) *
Если речь об исходниках FreeRTOS, то там используется макрос configASSERT, и именно по умолчанию там реализация - "ничего".
FreeRTOS\Source\include\FreeRTOS.h:
Код
#ifndef configASSERT
    #define configASSERT( x )
    #define configASSERT_DEFINED 0
#else
    #define configASSERT_DEFINED 1
#endif

Считаю легкомысленным оставлять пустую реализацию configASSERT. configASSERT у меня равен assert.

Цитата(den_po @ Sep 30 2015, 12:46) *
В вашем случае нужно сохранять результат вызова в переменные и в ассертах использовать именно их.
Попробуйте скомпилировать ваш проект в релизной конфигурации (с объявленным в настройках препроцессора макросом NDEBUG) и убедитесь.

Понял о чем вы. О том что заворачивание в assert может привести к тому что функции вообще не вызовется. Не мой случай, у меня assert - это мой макрос, на него не влияют никакие настройки. Ну и прежде чем использовать какой-то макрос конечно надо посмотреть как он реализован и что на него влияет.

Цитата(den_po @ Sep 30 2015, 12:46) *
в assert и подобные макросы заворачивают вызовы функций, но только те, удаление которых не влияет на ход работы программы.

assert - это проверка "контракта". Если assert не прошел - дальнейшее выполение программы не имеет смысла.
Go to the top of the page
 
+Quote Post
den_po
сообщение Sep 30 2015, 11:38
Сообщение #16


Частый гость
**

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(turnon @ Sep 30 2015, 14:44) *
Понял о чем вы. О том что заворачивание в assert может привести к тому что функции вообще не вызовется. Не мой случай, у меня assert - это мой макрос, на него не влияют никакие настройки. Ну и прежде чем использовать какой-то макрос конечно надо посмотреть как он реализован и что на него влияет.

assert - часть стандартной библиотеки, что на него влияет, описано в стандарте.
Рассчитывать, что ваш код всегда будет работать с перепиленной вами версией макроса, - раскидывать грабли.

Цитата(turnon @ Sep 30 2015, 14:44) *
assert - это проверка "контракта". Если assert не прошел - дальнейшее выполение программы не имеет смысла.

Во время отладки да, а при работе у конечных пользователей остановка программы зачастую гораздо хуже продолжения её выполнения.
Go to the top of the page
 
+Quote Post
turnon
сообщение Sep 30 2015, 11:50
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Цитата(den_po @ Sep 30 2015, 14:38) *
Во время отладки да, а при работе у конечных пользователей остановка программы зачастую гораздо хуже продолжения её выполнения.

assert применяется для проверки критичных условий, выход за которые означает крах.
Если assert сработал - дальнейшее выполнение программы опасно, может привести к непредсказуемым последствиям. При сработке assert правильное поведение (имхо) - фиксация файла и строки в энергонезависимой памяти и ресет.

Go to the top of the page
 
+Quote Post
den_po
сообщение Sep 30 2015, 12:21
Сообщение #18


Частый гость
**

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(turnon @ Sep 30 2015, 15:50) *
assert применяется для проверки критичных условий, выход за которые означает крах.

Нет. Ассерт - просто средство отладки. Он нужен программисту, но никак не конечному пользователю.

Цитата(turnon @ Sep 30 2015, 15:50) *
Если assert сработал - дальнейшее выполнение программы опасно, может привести к непредсказуемым последствиям. При сработке assert правильное поведение (имхо) - фиксация файла и строки в энергонезависимой памяти и ресет.

Если б всё было так, всякие мобильники и телевизоры постоянно бы висли или вырубались. Ну и в иных местах просто были бы тормознее.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 30 2015, 12:37
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (turnon @ Sep 30 2015, 11:50) *
Вот для примера сделал минимальный проект в IAR (пристегнутый zip). empty\tmp\Debug\List\Project.map.
В объекте gLog есть поле _inited и _fileSpec, а в map-файле этих полей в явном виде нет. Почему?

Почему УЖЕ писал:
QUOTE
Если _semaphore элемент структуры, то в map будет адрес и размер структуры

То-же естесественно, относится к любым объектам. Данные объекта gLog в map есть - 44 байта. Расположение переременных Вы сами задали:
QUOTE
class Log
{
private:
int _inited;
char _fileSpec[40];

Так-что что может быть непонятным-то? В структурах и классах могли-бы вообще и map не смотреть - Вы же своими собственными руками описали что рядом с чем находится.

Посмотите на класс в Вы который зарыли _semaphore и все будет ясно.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
turnon
сообщение Sep 30 2015, 17:36
Сообщение #20


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Цитата(zltigo @ Sep 30 2015, 15:37) *
Данные объекта gLog в map есть - 44 байта. Расположение переременных Вы сами задали

А, получается просто в виде адресов. Предполагал что там будут имена переменных, а имен там нет.


Цитата(den_po @ Sep 30 2015, 15:21) *
Нет. Ассерт - просто средство отладки. Он нужен программисту, но никак не конечному пользователю.

Конечному пользователю и дебаггер не нужен. Ему нужен корректно работающий девайс.
Нет программ без ошибок. Вы же не будете утверждать обратное?

Цитата(den_po @ Sep 30 2015, 15:21) *
Если б всё было так, всякие мобильники и телевизоры постоянно бы висли или вырубались. Ну и в иных местах просто были бы тормознее.

Отсюда я делаю вывод, что в мобильниках и телевизорах куча ассертов, которые отключены из-за того, что если бы они были включены, мобильники и телевизоры постоянно бы висли или вырубались?


Цитата(zltigo @ Sep 29 2015, 18:16) *
Посему, хотите верьте, хотите нет, но затираете Вы явным образом сами. Ну или не совсем явным. Смотрите, например, на какой-нибудь массив расположенный рядом с этой переменной.

Действительно обнаружил неверную трактовку размера массива. Массив состоит из uint64, а я его размер узнавал с помощью sizeof, без учета что размер элемента не 1 байт... Сказывается очень много работы со строками, где sizeof и равен размеру массива.

Мораль - если что-то не работает, начинайте с того места, где это не работает. А не с подозрений на компилятор, гейтса и фазу луны.

Но зато в процессе открыл для себя map-файлы. И раньше знал что есть что-то такое, но не лазил. А в map файле очень хорошо видно расход ОЗУ по модулям и переменным. Правда жаль что в map файле нет имен полей (переменных) объекта, только методы и глобальные переменные.



Цитата(megajohn @ Sep 29 2015, 19:17) *
можно через JTAG поставить DataBreakpoint и не париться

Отличная штука, и применял же такое в разработке для ПК, но тут как-то не догадался.
Go to the top of the page
 
+Quote Post
den_po
сообщение Sep 30 2015, 21:11
Сообщение #21


Частый гость
**

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(turnon @ Sep 30 2015, 22:36) *
Конечному пользователю и дебаггер не нужен. Ему нужен корректно работающий девайс.
Нет программ без ошибок. Вы же не будете утверждать обратное?

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

Цитата(turnon @ Sep 30 2015, 22:36) *
Отсюда я делаю вывод, что в мобильниках и телевизорах куча ассертов, которые отключены из-за того, что если бы они были включены, мобильники и телевизоры постоянно бы висли или вырубались?

Отключены они из-за того, что пользователю они ни к чему. Лучше пользователю от них не станет, а хуже может.
Они и разработчикам не нужны в большинстве случаев. Я не про ассерты вообще и разработчиков вообще, я про конкретно ситуацию с мобилками и телевизорами. У разработчиков/тестеров есть дебаг сборки прошивок, но и там включают ассерты не везде, а лишь в части модулей/библиотек.

Закруглюсь, пожалуй, с этой темой. Сказал уже всё, что мог, нового ничего не добавлю.
Go to the top of the page
 
+Quote Post
turnon
сообщение Sep 30 2015, 21:15
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Цитата(den_po @ Oct 1 2015, 00:11) *
Виснущий девайс для пользователя гораздо хуже работающего кое как. Тем более, что пользователь зачастую и не замечает, что перед ним это самое "кое как".

Кое-как он работать не будет. Если по ассерту не прошло условие, но ассерт отключен - дальше работа приведет скорее всего к зависанию/хардфаулту и сбросу по вочдогу, в худшем - к непредусмотренному сценарию управления исполнительным механизмом.

А иначе разработчик неправильно применяет ассерты.

Сообщение отредактировал turnon - Sep 30 2015, 21:16
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 03:34
Рейтинг@Mail.ru


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