esp_timer: fix for the case when timer is deleted in callback

Timer callback can delete the timer. If CONFIG_ESP_TIMER_PROFILING was
enabled, this caused an access to invalid (freed) memory.
This fix adds a pointer to track the timer while executing the callback.
This is needed so that we can check if callback deletes the timer,
in which case we won't try updating profiling counters for this timer
after the callback is done.
This commit is contained in:
Ivan Grokhotkov
2017-11-24 17:33:13 +08:00
parent 1d5389668b
commit 6e7eb3c776
2 changed files with 50 additions and 3 deletions

View File

@@ -4,6 +4,7 @@
#include <sys/time.h>
#include "unity.h"
#include "esp_timer.h"
#include "esp_heap_caps.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
@@ -379,3 +380,37 @@ TEST_CASE("Can dump esp_timer stats", "[esp_timer]")
{
esp_timer_dump(stdout);
}
TEST_CASE("Can delete timer from callback", "[esp_timer]")
{
typedef struct {
SemaphoreHandle_t notify_from_timer_cb;
esp_timer_handle_t timer;
} test_arg_t;
void timer_func(void* varg)
{
test_arg_t arg = *(test_arg_t*) varg;
esp_timer_delete(arg.timer);
printf("Timer %p is deleted\n", arg.timer);
xSemaphoreGive(arg.notify_from_timer_cb);
}
test_arg_t args = {
.notify_from_timer_cb = xSemaphoreCreateBinary(),
};
esp_timer_create_args_t timer_args = {
.callback = &timer_func,
.arg = &args,
.name = "self_deleter"
};
esp_timer_create(&timer_args, &args.timer);
esp_timer_start_once(args.timer, 10000);
TEST_ASSERT_TRUE(xSemaphoreTake(args.notify_from_timer_cb, 1000 / portTICK_PERIOD_MS));
printf("Checking heap at %p\n", args.timer);
TEST_ASSERT_TRUE(heap_caps_check_integrity_addr((intptr_t) args.timer, true));
vSemaphoreDelete(args.notify_from_timer_cb);
}