Jump to content

    

Как выяснить текущую выполняемую строку задачи

Подскажите пожалуйста как словить баг в коде задачи.

IAR 8.30.2, нахожусь в отладке. Задача "зависла" - не останавливается на брейкпоинтах в начале и в конце while(1) в цикле задачи.

Код задачи довольно разветвленный, брейкпоинты везде поставить невозможно. Есть ли возможность и как можно узнать где сейчас (на какой строке) выполняется задача? Может есть какой-то адрес текущей выполняемой инструкции задачи где-то можно посмотреть и потом по нему перейти к строке в исходнике?

Share this post


Link to post
Share on other sites
2 minutes ago, turnon said:

Есть ли возможность и как можно узнать где сейчас (на какой строке)

printf? Или не совсем понятен ваш вопрос.

 

3 minutes ago, turnon said:

Задача "зависла" - не останавливается на брейкпоинтах в начале и в конце while(1) в цикле задачи.

Как это понять "зависла"? А что-нибудь вообще происходит с прибором? Что-то мигает, переключается? Вы можете остановить отладчик в любой момент времени, посмотреть, что вообще выполняется. И да, не выбросил ли оптимизатор тело задачи?

Share this post


Link to post
Share on other sites
8 minutes ago, haker_fox said:

printf? Или не совсем понятен ваш вопрос.

Как это понять "зависла"? А что-нибудь вообще происходит с прибором? Что-то мигает, переключается? Вы можете остановить отладчик в любой момент времени, посмотреть, что вообще выполняется. И да, не выбросил ли оптимизатор тело задачи?

Код задачи очень разветвленный, printf расставлять - это на неделю. Все остальные задачи работают, все ок, но одна задача зависла где то внутри while(1).

Share this post


Link to post
Share on other sites

Здесь, на мой взгляд, только тщательный анализ того, что написано в задаце. Или ставить брекпоинты и ждать.

Share this post


Link to post
Share on other sites
48 minutes ago, turnon said:

Есть ли возможность и как можно узнать где сейчас (на какой строке) выполняется задача? Может есть какой-то адрес текущей выполняемой инструкции задачи где-то можно посмотреть и потом по нему перейти к строке в исходнике?

Можно извлечь текущий адрес из стека задачи.

Share this post


Link to post
Share on other sites

У IAR-а есть плагин для FreeRTOS, который может показывать текущее состояние задачи (выполняется, заблокирована и т.д.). Плагин включается в настройках проекта Debugger->Plugins->"галочка напротив "FreeRTOS and OpenRTOS". Соответственно первым делом имеет смысл посмотреть, не является ли задача полностью заблокированной все время (или вообще она хотя бы создается). 

 

Следующим шагом, можно добавить задачу мониторинга, которая будет с заданным интервалом вызываться и выводить с помощью printf в отладку состояние всех задач (смотреть в сторону uxTaskGetSystemState или вот эту статью https://habr.com/ru/post/352782/)

 

Если задача действительно запускается и выполняется (хотя судя по описанию - это маловероятно и она скорее всего полностью заблокирована), то ставить breakpoint или по шагам выяснить какой из while(1) висит.

Edited by Grigorij

Share this post


Link to post
Share on other sites
53 minutes ago, turnon said:

все ок, но одна задача зависла где то внутри while(1).

Гм. Если остальные задачи работают, то "зависшая" что-то выполняет или ждёт. Скорее всего, ждёт. Это моё интуитивное предположение на основе моего скромного опыта. Попробуйте поднять задачу консоли (она примером идёт), и выведите task list. В нём будут статусы задач, размеры стека. Можете исопльзовать плагин для вашей среды разработки. Но по мне консоль более удобна.

З.Ы. Может быть вы вообще не создаёте эту задачу???) Посмотрите, есть ли для неё xCreateTask.

З.Ы.Ы. Может быть эта задача не получает управления? Например, у неё приоритет ниже, чем у другой, готовой к исполнению. А та, готовая, молотит процессором без остановки и не отдаёт управление. Здесь вам следует сверится с механизмом планировщика оси. Он подробно описан на сайте.

Share this post


Link to post
Share on other sites

если тупо и универсально, то

volatile int line_dbg = 0;

#define DBG line_dbg=__LINE__

func1(); DBG;

func2(); DBG;

func3(); DBG;

Share this post


Link to post
Share on other sites
2 hours ago, haker_fox said:

З.Ы. Может быть вы вообще не создаёте эту задачу???) Посмотрите, есть ли для неё xCreateTask.

Задача создается, работает долгое время. Ловлю зависание 1-2 раза в сутки. Приоритеты у всех задач одинаковые. Скорее всего где-то в бизнес-логике завис.

1 hour ago, megajohn said:

если тупо и универсально, то

volatile int line_dbg = 0;

#define DBG line_dbg=__LINE__

func1(); DBG;

func2(); DBG;

func3(); DBG;

Идея интересная. Попробую на все кодовую базу нацепить автозаменой.

Share this post


Link to post
Share on other sites
3 hours ago, aaarrr said:

Можно извлечь текущий адрес из стека задачи.

Скажите пожалуйста, как это сделать.

Share this post


Link to post
Share on other sites

Вызываем vTaskGetInfo(), получаем указатель на стек задачи, разбираем его (формат смотрим в файлах порта).

Share this post


Link to post
Share on other sites

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