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

 
 
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

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

 


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


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