Просмотр исходного кода

[FL-1486] Fix leaks and leak-sanitizer (#538)

* [FL-1486] Fix leaks and leak-sanitizer
* Move free_heap to AppLoaderState
* App-loader: better heap logging.

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
Albert Kharisov 4 лет назад
Родитель
Сommit
158c859bdc
2 измененных файлов с 24 добавлено и 3 удалено
  1. 23 3
      applications/app-loader/app-loader.c
  2. 1 0
      core/furi/memmgr_heap.c

+ 23 - 3
applications/app-loader/app-loader.c

@@ -1,4 +1,5 @@
 #include "app-loader.h"
 #include "app-loader.h"
+#include "api-hal-delay.h"
 
 
 #define APP_LOADER_TAG "app_loader"
 #define APP_LOADER_TAG "app_loader"
 
 
@@ -7,6 +8,7 @@ typedef struct {
     const FlipperApplication* current_app;
     const FlipperApplication* current_app;
     string_t args;
     string_t args;
     Cli* cli;
     Cli* cli;
+    size_t free_heap_size;
 } AppLoaderState;
 } AppLoaderState;
 
 
 static AppLoaderState state;
 static AppLoaderState state;
@@ -90,11 +92,29 @@ bool app_loader_start(const char* name, const char* args) {
 
 
 void app_loader_thread_state_callback(FuriThreadState thread_state, void* context) {
 void app_loader_thread_state_callback(FuriThreadState thread_state, void* context) {
     furi_assert(context);
     furi_assert(context);
-    if(thread_state == FuriThreadStateStopped) {
+
+    AppLoaderState* state = context;
+
+    if(thread_state == FuriThreadStateRunning) {
+        state->free_heap_size = xPortGetFreeHeapSize();
+    } else if(thread_state == FuriThreadStateStopped) {
+        /*
+         * Current Leak Sanitizer assumes that memory is allocated and freed
+         * inside one thread. Timers are allocated in one task, but freed in
+         * Timer-Task thread, and xTimerDelete() just put command to queue.
+         * To avoid some bad cases there are few fixes:
+         * 1) delay for Timer to process commands
+         * 2) there are 'heap diff' which shows difference in heap before task
+         * started and after task completed. In process of leakage monitoring
+         * both values should be taken into account.
+         */
+        delay(20);
+        int heap_diff = state->free_heap_size - xPortGetFreeHeapSize();
         FURI_LOG_I(
         FURI_LOG_I(
             APP_LOADER_TAG,
             APP_LOADER_TAG,
-            "Application thread stopped, heap leaked: %d",
-            furi_thread_get_heap_size(state.thread));
+            "Application thread stopped. Heap allocation balance: %d. Thread allocation balance: %d.",
+            heap_diff,
+            furi_thread_get_heap_size(state->thread));
         api_hal_power_insomnia_exit();
         api_hal_power_insomnia_exit();
     }
     }
 }
 }

+ 1 - 0
core/furi/memmgr_heap.c

@@ -142,6 +142,7 @@ void memmgr_heap_enable_thread_trace(osThreadId_t thread_id) {
         MemmgrHeapAllocDict_t alloc_dict;
         MemmgrHeapAllocDict_t alloc_dict;
         MemmgrHeapAllocDict_init(alloc_dict);
         MemmgrHeapAllocDict_init(alloc_dict);
         MemmgrHeapThreadDict_set_at(memmgr_heap_thread_dict, (uint32_t)thread_id, alloc_dict);
         MemmgrHeapThreadDict_set_at(memmgr_heap_thread_dict, (uint32_t)thread_id, alloc_dict);
+        MemmgrHeapAllocDict_clear(alloc_dict);
         memmgr_heap_thread_trace_depth--;
         memmgr_heap_thread_trace_depth--;
     }
     }
     (void)xTaskResumeAll();
     (void)xTaskResumeAll();