From 2333a6a262ed147cca35be7187032db87d225390 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Sun, 16 Mar 2025 08:49:29 +0200 Subject: [PATCH] feat(core): log GC info in case of OOM Enabled on debug firmware and non-frozen emulator. [no changelog] --- core/SConscript.firmware | 10 +++++- core/SConscript.unix | 6 ++-- .../upymod/modtrezorutils/modtrezorutils.c | 36 +++++++++++++++++-- core/mocks/generated/trezorutils.pyi | 5 +++ core/src/trezor/utils.py | 7 ++++ vendor/micropython | 2 +- 6 files changed, 58 insertions(+), 8 deletions(-) diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 583143cae7..fa924c877a 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -395,9 +395,17 @@ ui.init_ui(TREZOR_MODEL, "firmware", RUST_UI_FEATURES) SOURCE_QSTR = SOURCE_MOD + SOURCE_MICROPYTHON + SOURCE_MICROPYTHON_SPEED +if PYOPT == '0': + DEBUG_FLAGS = "-DMICROPY_OOM_CALLBACK=1" +else: + DEBUG_FLAGS = "-DMICROPY_OOM_CALLBACK=0" + env = Environment( ENV=os.environ, - CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DPYOPT={PYOPT} -DBOOTLOADER_QA={int(BOOTLOADER_QA)} -DBITCOIN_ONLY={BITCOIN_ONLY}", + CFLAGS=( + f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DPYOPT={PYOPT} " + f"-DBOOTLOADER_QA={int(BOOTLOADER_QA)} -DBITCOIN_ONLY={BITCOIN_ONLY} {DEBUG_FLAGS}" + ), CPPDEFINES_IMPLICIT=[], CPPDEFPREFIX="-D'", CPPDEFSUFFIX="'", diff --git a/core/SConscript.unix b/core/SConscript.unix index 17c5a1effc..52e1b52a95 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -422,13 +422,13 @@ ui.init_ui(TREZOR_MODEL, "firmware", RUST_UI_FEATURES) SOURCE_QSTR = SOURCE_MOD + SOURCE_MICROPYTHON + SOURCE_UNIX if PYOPT == '0' or not FROZEN: - STATIC="-DSTATIC=" + DEBUG_FLAGS = "-DMICROPY_OOM_CALLBACK=1 -DSTATIC=" else: - STATIC="" + DEBUG_FLAGS = "-DMICROPY_OOM_CALLBACK=0" env = Environment( ENV=os.environ, - CFLAGS=ARGUMENTS.get("CFLAGS", "") + f" -DCONFIDENTIAL= -DPYOPT={PYOPT} -DBITCOIN_ONLY={BITCOIN_ONLY} {STATIC}", + CFLAGS=ARGUMENTS.get("CFLAGS", "") + f" -DCONFIDENTIAL= -DPYOPT={PYOPT} -DBITCOIN_ONLY={BITCOIN_ONLY} {DEBUG_FLAGS}", CPPDEFPREFIX="-D'", CPPDEFSUFFIX="'", ) diff --git a/core/embed/upymod/modtrezorutils/modtrezorutils.c b/core/embed/upymod/modtrezorutils/modtrezorutils.c index 73038b56af..f34ce4df41 100644 --- a/core/embed/upymod/modtrezorutils/modtrezorutils.c +++ b/core/embed/upymod/modtrezorutils/modtrezorutils.c @@ -20,6 +20,9 @@ #include #include +#if MICROPY_OOM_CALLBACK +#include +#endif #include "py/objstr.h" #include "py/runtime.h" @@ -243,7 +246,8 @@ STATIC mp_obj_t mod_trezorutils_sd_hotswap_enabled(void) { STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_sd_hotswap_enabled_obj, mod_trezorutils_sd_hotswap_enabled); -#if !PYOPT && LOG_STACK_USAGE +#if !PYOPT +#if LOG_STACK_USAGE /// def zero_unused_stack() -> None: /// """ /// Zero unused stack memory. @@ -275,7 +279,27 @@ STATIC mp_obj_t mod_trezorutils_estimate_unused_stack(void) { STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_estimate_unused_stack_obj, mod_trezorutils_estimate_unused_stack); -#endif // !PYOPT && LOG_STACK_USAGE +#endif // LOG_STACK_USAGE + +#if MICROPY_OOM_CALLBACK +static void gc_oom_callback(void) { + gc_dump_info(); +} + +/// if __debug__: +/// def enable_oom_dump() -> None: +/// """ +/// Dump GC info in case of an OOM. +/// """ +STATIC mp_obj_t mod_trezorutils_enable_oom_dump(void) { + gc_set_oom_callback(gc_oom_callback); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_enable_oom_dump_obj, + mod_trezorutils_enable_oom_dump); +#endif // MICROPY_OOM_CALLBACK + +#endif // !PYOPT /// def reboot_to_bootloader( /// boot_command : int = 0, @@ -482,11 +506,17 @@ STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = { MP_ROM_PTR(&mod_trezorutils_unit_packaging_obj)}, {MP_ROM_QSTR(MP_QSTR_unit_btconly), MP_ROM_PTR(&mod_trezorutils_unit_btconly_obj)}, -#if !PYOPT && LOG_STACK_USAGE +#if !PYOPT +#if LOG_STACK_USAGE {MP_ROM_QSTR(MP_QSTR_zero_unused_stack), MP_ROM_PTR(&mod_trezorutils_zero_unused_stack_obj)}, {MP_ROM_QSTR(MP_QSTR_estimate_unused_stack), MP_ROM_PTR(&mod_trezorutils_estimate_unused_stack_obj)}, +#endif +#if MICROPY_OOM_CALLBACK + {MP_ROM_QSTR(MP_QSTR_enable_oom_dump), + MP_ROM_PTR(&mod_trezorutils_enable_oom_dump_obj)}, +#endif #endif {MP_ROM_QSTR(MP_QSTR_sd_hotswap_enabled), MP_ROM_PTR(&mod_trezorutils_sd_hotswap_enabled_obj)}, diff --git a/core/mocks/generated/trezorutils.pyi b/core/mocks/generated/trezorutils.pyi index 65185bcd50..35c463cdb9 100644 --- a/core/mocks/generated/trezorutils.pyi +++ b/core/mocks/generated/trezorutils.pyi @@ -100,6 +100,11 @@ def estimate_unused_stack() -> int: """ Estimate unused stack size. """ +if __debug__: + def enable_oom_dump() -> None: + """ + Dump GC info in case of an OOM. + """ # upymod/modtrezorutils/modtrezorutils.c diff --git a/core/src/trezor/utils.py b/core/src/trezor/utils.py index afe88773d0..ebb0057560 100644 --- a/core/src/trezor/utils.py +++ b/core/src/trezor/utils.py @@ -125,6 +125,13 @@ def presize_module(modname: str, size: int) -> None: if __debug__: from ubinascii import hexlify + try: + from trezorutils import enable_oom_dump + + enable_oom_dump() + except ImportError: + pass + def mem_dump(filename: str) -> None: from micropython import mem_info diff --git a/vendor/micropython b/vendor/micropython index d2d97062f7..e4d81eb380 160000 --- a/vendor/micropython +++ b/vendor/micropython @@ -1 +1 @@ -Subproject commit d2d97062f7ef731109e895760035b4e3e047ad8c +Subproject commit e4d81eb3802b567960ae9405b33c0c9e6efe7f0d