From 70a628f2c8457200b386603c2eb53ad66507849d Mon Sep 17 00:00:00 2001 From: Hugo Saint-Vignes Date: Thu, 27 Aug 2020 16:29:43 +0200 Subject: [PATCH] [apps] Fix Python assert crash on malloc free Change-Id: I48f86422f7d6af5227e2556e6ef531dfad696da4 --- apps/main.cpp | 23 +++++++++++++++++++++++ ion/include/ion.h | 2 ++ python/port/port.cpp | 9 +++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/apps/main.cpp b/apps/main.cpp index d0dcf00b7..51a95e2b9 100644 --- a/apps/main.cpp +++ b/apps/main.cpp @@ -2,6 +2,19 @@ #include "global_preferences.h" #include +#if PLATFORM_DEVICE +// On device, stack start address is always known. TODO : Factorize address +static void * s_stackStart = reinterpret_cast(0x20000000 + 256*1024); +#else +// Stack start will be defined in ion_main. +static void * s_stackStart = nullptr; +#endif + +void * Ion::stackStart() { + assert(s_stackStart != nullptr); + return s_stackStart; +} + #define DUMMY_MAIN 0 #if DUMMY_MAIN @@ -60,6 +73,16 @@ void ion_main(int argc, const char * const argv[]) { } } #endif + +#if !PLATFORM_DEVICE + /* s_stackStart must be defined as early as possible to ensure that there + * cannot be allocated memory pointers before. Otherwise, with MicroPython for + * example, stack pointer could go backward after initialization and allocated + * memory pointers could be overlooked during mark procedure. */ + volatile int stackTop; + s_stackStart = (void *)(&stackTop); +#endif + AppsContainer::sharedAppsContainer()->run(); } diff --git a/ion/include/ion.h b/ion/include/ion.h index 45a8e5559..47c010614 100644 --- a/ion/include/ion.h +++ b/ion/include/ion.h @@ -46,6 +46,8 @@ uint32_t random(); // Decompress data void decompress(const uint8_t * src, uint8_t * dst, int srcSize, int dstSize); +// Returns address to the first object that can be allocated on stack +void * stackStart(); // Tells whether the stack pointer is within acceptable bounds bool stackSafe(); diff --git a/python/port/port.cpp b/python/port/port.cpp index 49ecf055c..c9880aed1 100644 --- a/python/port/port.cpp +++ b/python/port/port.cpp @@ -122,15 +122,16 @@ void MicroPython::init(void * heapStart, void * heapEnd) { static mp_obj_t pystack[1024]; mp_pystack_init(pystack, &pystack[MP_ARRAY_SIZE(pystack)]); #endif - - volatile int stackTop; - void * stackTopAddress = (void *)(&stackTop); /* We delimit the stack part that will be used by Python. The stackTop is the * address of the first object that can be allocated on Python stack. This * boundaries are used: * - by gc_collect to determine where to collect roots of the objects that * must be kept on the heap - * - to check if the maximal recursion depth has been reached. */ + * - to check if the maximal recursion depth has been reached. + * Current stack pointer could go backward after initialization. A stack start + * pointer defined in main is therefore used. */ + void * stackTopAddress = Ion::stackStart(); + #if MP_PORT_USE_STACK_SYMBOLS mp_stack_set_top(stackTopAddress); size_t stackLimitInBytes = (char *)stackTopAddress - (char *)&_stack_end;