Skip to content
59 changes: 59 additions & 0 deletions applications/debug/crash_test/crash_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,49 @@ typedef enum {
CrashTestSubmenuAssertMessage,
CrashTestSubmenuCrash,
CrashTestSubmenuHalt,
CrashTestSubmenuHeapUnderflow,
CrashTestSubmenuHeapOverflow,
} CrashTestSubmenu;

static void crash_test_corrupt_heap_underflow(void) {
const size_t block_size = 1000;
const size_t underflow_size = 123;
uint8_t* block = malloc(block_size);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow" // that's what we want!
memset(block - underflow_size, 0xDD, underflow_size); // -V769
#pragma GCC diagnostic pop

free(block); // should crash here (if compiled with DEBUG=1)

// If we got here, the heap wasn't able to detect our corruption and crash
furi_crash("Test failed, should've crashed with \"FreeRTOS Assert\" error");
}

static void crash_test_corrupt_heap_overflow(void) {
const size_t block_size = 1000;
const size_t overflow_size = 123;
uint8_t* block1 = malloc(block_size);
uint8_t* block2 = malloc(block_size);
memset(block2, 12, 34); // simulate use to avoid optimization // -V597 // -V1086

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow" // that's what we want!
memset(block1 + block_size, 0xDD, overflow_size); // -V769 // -V512
#pragma GCC diagnostic pop

uint8_t* block3 = malloc(block_size);
memset(block3, 12, 34); // simulate use to avoid optimization // -V597 // -V1086

free(block3); // should crash here (if compiled with DEBUG=1)
free(block2);
free(block1);

// If we got here, the heap wasn't able to detect our corruption and crash
furi_crash("Test failed, should've crashed with \"FreeRTOS Assert\" error");
}

static void crash_test_submenu_callback(void* context, uint32_t index) {
CrashTest* instance = (CrashTest*)context;
UNUSED(instance);
Expand All @@ -49,6 +90,12 @@ static void crash_test_submenu_callback(void* context, uint32_t index) {
case CrashTestSubmenuHalt:
furi_halt("Crash test: furi_halt");
break;
case CrashTestSubmenuHeapUnderflow:
crash_test_corrupt_heap_underflow();
break;
case CrashTestSubmenuHeapOverflow:
crash_test_corrupt_heap_overflow();
break;
default:
furi_crash();
}
Expand Down Expand Up @@ -94,6 +141,18 @@ CrashTest* crash_test_alloc(void) {
instance->submenu, "Crash", CrashTestSubmenuCrash, crash_test_submenu_callback, instance);
submenu_add_item(
instance->submenu, "Halt", CrashTestSubmenuHalt, crash_test_submenu_callback, instance);
submenu_add_item(
instance->submenu,
"Heap underflow",
CrashTestSubmenuHeapUnderflow,
crash_test_submenu_callback,
instance);
submenu_add_item(
instance->submenu,
"Heap overflow",
CrashTestSubmenuHeapOverflow,
crash_test_submenu_callback,
instance);

return instance;
}
Expand Down
6 changes: 5 additions & 1 deletion applications/main/infrared/views/infrared_progress_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ void infrared_progress_view_set_paused(InfraredProgressView* instance, bool is_p

bool infrared_progress_view_input_callback(InputEvent* event, void* context) {
InfraredProgressView* instance = context;
if(event->type != InputTypeShort && event->type != InputTypeRepeat) return false;

if(event->type == InputTypePress || event->type == InputTypeRelease) {
return false;
}

if(!instance->input_callback) return false;

with_view_model(
Expand Down
2 changes: 1 addition & 1 deletion applications/system/hid_app/views/hid_mouse_clicker.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static bool hid_mouse_clicker_input_callback(InputEvent* event, void* context) {
bool consumed = false;
bool rate_changed = false;

if(event->type != InputTypeShort && event->type != InputTypeRepeat) {
if(event->type == InputTypePress || event->type == InputTypeRelease) {
return false;
}

Expand Down
6 changes: 4 additions & 2 deletions furi/core/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,13 @@ static void __furi_print_bt_stack_info(void) {

static void __furi_print_heap_info(void) {
furi_log_puts("\r\n\t heap total: ");
__furi_put_uint32_as_text(xPortGetTotalHeapSize());
__furi_put_uint32_as_text(configTOTAL_HEAP_SIZE);
furi_log_puts("\r\n\t heap free: ");
__furi_put_uint32_as_text(xPortGetFreeHeapSize());
HeapStats_t heap_stats;
vPortGetHeapStats(&heap_stats);
furi_log_puts("\r\n\t heap watermark: ");
__furi_put_uint32_as_text(xPortGetMinimumEverFreeHeapSize());
__furi_put_uint32_as_text(heap_stats.xMinimumEverFreeBytesRemaining);
}

static void __furi_print_name(bool isr) {
Expand Down
3 changes: 2 additions & 1 deletion furi/core/memmgr.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "memmgr.h"
#include <string.h>
#include <furi_hal_memory.h>
#include <FreeRTOS.h>

extern void* pvPortMalloc(size_t xSize);
extern void vPortFree(void* pv);
Expand Down Expand Up @@ -51,7 +52,7 @@ size_t memmgr_get_free_heap(void) {
}

size_t memmgr_get_total_heap(void) {
return xPortGetTotalHeapSize();
return configTOTAL_HEAP_SIZE;
}

size_t memmgr_get_minimum_free_heap(void) {
Expand Down
Loading
Loading