diff --git a/ci/test.yml b/ci/test.yml index 16443951f..c97b85c8d 100644 --- a/ci/test.yml +++ b/ci/test.yml @@ -359,3 +359,24 @@ hardware legacy btconly device test: - ci/hardware_tests/video*.mp4 expire_in: 2 days when: always + +core unix memory profiler: + stage: test + when: manual + needs: [] + variables: + PYOPT: "0" + TREZOR_MEMPERF: "1" + PYTEST_TIMEOUT: "600" + script: + - nix-shell --run "poetry run make -C core build_unix_frozen" + - nix-shell --run "poetry run make -C core test_emu" + - nix-shell --run "mkdir core/prof/memperf-html" + - nix-shell --run "poetry run core/tools/alloc.py --alloc-data=core/src/alloc_data.txt html core/prof/memperf-html" + artifacts: + name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA" + paths: + - tests/trezor.log + - core/prof/memperf-html + expire_in: 1 week + when: always diff --git a/core/Makefile b/core/Makefile index 3aa71d7b6..5e56d78fc 100644 --- a/core/Makefile +++ b/core/Makefile @@ -22,6 +22,7 @@ PYOPT ?= 1 BITCOIN_ONLY ?= 0 RDI ?= 1 TREZOR_MODEL ?= T +TREZOR_MEMPERF ?= 0 STLINK_VER ?= v2 OPENOCD = openocd -f interface/stlink-$(STLINK_VER).cfg -c "transport select hla_swd" -f target/stm32f4x.cfg @@ -149,7 +150,7 @@ build_unix: res ## build unix port $(SCONS) CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_MODEL="$(TREZOR_MODEL)" BITCOIN_ONLY="$(BITCOIN_ONLY)" build_unix_frozen: res build_cross ## build unix port with frozen modules - $(SCONS) CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_MODEL="$(TREZOR_MODEL)" PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_EMULATOR_FROZEN=1 + $(SCONS) CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_MODEL="$(TREZOR_MODEL)" PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_MEMPERF=$(TREZOR_MEMPERF) TREZOR_EMULATOR_FROZEN=1 build_unix_debug: res ## build unix port $(SCONS) --max-drift=1 CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_MODEL="$(TREZOR_MODEL)" TREZOR_EMULATOR_ASAN=1 TREZOR_EMULATOR_DEBUGGABLE=1 diff --git a/core/SConscript.unix b/core/SConscript.unix index 5ed1ceab4..993a5f439 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -348,6 +348,11 @@ if ARGUMENTS.get('TREZOR_EMULATOR_DEBUGGABLE', 0): COPT=' -O0 -ggdb', STRIP='true', ) +if ARGUMENTS.get('TREZOR_MEMPERF', '0') == '1': + CPPDEFINES_MOD += [ + ('MICROPY_TREZOR_MEMPERF', '\(1\)') + ] + env.Replace( TREZOR_MODEL=TREZOR_MODEL, ) diff --git a/core/emu.py b/core/emu.py index 6863aa5f4..f1dc9173e 100755 --- a/core/emu.py +++ b/core/emu.py @@ -89,6 +89,7 @@ def _from_env(name): @click.option("-D", "--debugger", is_flag=True, help="Run emulator in debugger (gdb/lldb)") @click.option("--executable", type=click.Path(exists=True, dir_okay=False), default=os.environ.get("MICROPYTHON"), help="Alternate emulator executable") @click.option("-g", "--profiling/--no-profiling", default=_from_env("TREZOR_PROFILING"), help="Run with profiler wrapper") +@click.option("-G", "--alloc-profiling/--no-alloc-profiling", default=_from_env("TREZOR_MEMPERF"), help="Profile memory allocation (requires special micropython build)") @click.option("-h", "--headless", is_flag=True, help="Headless mode (no display)") @click.option("--heap-size", metavar="SIZE", default="20M", help="Configure heap size") @click.option("--main", help="Path to python main file") @@ -111,6 +112,7 @@ def cli( debugger, executable, profiling, + alloc_profiling, headless, heap_size, main, @@ -154,7 +156,7 @@ def cli( if watch and inotify is None: raise click.ClickException("inotify module is missing, install with pip") - if main and profiling: + if main and (profiling or alloc_profiling): raise click.ClickException("Cannot use --main and -g together") if slip0014 and mnemonics: @@ -169,7 +171,7 @@ def cli( if mnemonics and production: raise click.ClickException("Cannot load mnemonics in production mode") - if profiling: + if profiling or alloc_profiling: main_args = [str(PROFILING_WRAPPER)] elif main: main_args = [main] @@ -231,6 +233,9 @@ def cli( if log_memory: os.environ["TREZOR_LOG_MEMORY"] = "1" + if alloc_profiling: + os.environ["TREZOR_MEMPERF"] = "1" + if debugger: run_debugger(emulator) raise RuntimeError("run_debugger should not return")