Skip to content

Commit d3b1f0b

Browse files
committed
py/runtime: mp_stack_ctrl_init() should be called immediately on startup.
Calling it from mp_init() is too late for some ports (like Unix), and leads to incomplete stack frame being captured, with following GC issues. So, now each port should call mp_stack_ctrl_init() on its own, ASAP after startup, and taking special precautions so it really was called before stack variables get allocated (because if such variable with a pointer is missed, it may lead to over-collecting (typical symptom is segfaulting)).
1 parent 8502122 commit d3b1f0b

File tree

8 files changed

+25
-1
lines changed

8 files changed

+25
-1
lines changed

py/runtime.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ const mp_obj_module_t mp_module___main__ = {
6161

6262
void mp_init(void) {
6363
qstr_init();
64-
mp_stack_ctrl_init();
6564

6665
// no pending exceptions to start with
6766
MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;

qemu-arm/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
3232
}
3333

3434
int main(int argc, char **argv) {
35+
mp_stack_ctrl_init();
3536
mp_stack_set_limit(10240);
3637
void *heap = malloc(16 * 1024);
3738
gc_init(heap, (char*)heap + 16 * 1024);

qemu-arm/test_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ inline void do_str(const char *src) {
4949

5050
int main() {
5151
const char a[] = {"sim"};
52+
mp_stack_ctrl_init();
5253
mp_stack_set_limit(10240);
5354
void *heap = malloc(256 * 1024);
5455
gc_init(heap, (char*)heap + 256 * 1024);

stmhal/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ int main(void) {
335335

336336
// Stack limit should be less than real stack size, so we have a chance
337337
// to recover from limit hit. (Limit is measured in bytes.)
338+
mp_stack_ctrl_init();
338339
mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 1024);
339340

340341
/* STM32F4xx HAL library initialization:

teensy/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ int main(void) {
253253
#define SCB_CCR_STKALIGN (1 << 9)
254254
SCB_CCR |= SCB_CCR_STKALIGN;
255255

256+
mp_stack_ctrl_init();
256257
mp_stack_set_limit(10240);
257258

258259
pinMode(LED_BUILTIN, OUTPUT);

unix/main.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,19 @@ STATIC void set_sys_argv(char *argv[], int argc, int start_arg) {
376376
#define PATHLIST_SEP_CHAR ':'
377377
#endif
378378

379+
MP_NOINLINE int main_(int argc, char **argv);
380+
379381
int main(int argc, char **argv) {
382+
// We should capture stack top ASAP after start, and it should be
383+
// captured guaranteedly before any other stack variables are allocated.
384+
// For this, actual main (renamed main_) should not be inlined into
385+
// this function. main_() itself may have other functions inlined (with
386+
// their own stack variables), that's why we need this main/main_ split.
387+
mp_stack_ctrl_init();
388+
return main_(argc, argv);
389+
}
390+
391+
MP_NOINLINE int main_(int argc, char **argv) {
380392
mp_stack_set_limit(40000 * (BYTES_PER_WORD / 4));
381393

382394
pre_process_options(argc, argv);

unix/mpconfigport.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ void mp_unix_mark_exec(void);
214214
#define MP_PLAT_ALLOC_EXEC(min_size, ptr, size) mp_unix_alloc_exec(min_size, ptr, size)
215215
#define MP_PLAT_FREE_EXEC(ptr, size) mp_unix_free_exec(ptr, size)
216216

217+
#ifndef MP_NOINLINE
218+
#define MP_NOINLINE __attribute__((noinline))
219+
#endif
220+
217221
#if MICROPY_PY_OS_DUPTERM
218222
#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
219223
#else

windows/mpconfigport.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ extern const struct _mp_obj_module_t mp_module_time;
178178
#include "init.h"
179179
#include "sleep.h"
180180

181+
#ifdef __GNUC__
182+
#define MP_NOINLINE __attribute__((noinline))
183+
#endif
184+
181185
// MSVC specifics
182186
#ifdef _MSC_VER
183187

@@ -191,6 +195,7 @@ extern const struct _mp_obj_module_t mp_module_time;
191195
// CL specific overrides from mpconfig
192196

193197
#define NORETURN __declspec(noreturn)
198+
#define MP_NOINLINE __declspec(noinline)
194199
#define MP_LIKELY(x) (x)
195200
#define MP_UNLIKELY(x) (x)
196201
#define MICROPY_PORT_CONSTANTS { "dummy", 0 } //can't have zero-sized array

0 commit comments

Comments
 (0)