Skip to content

lua_lvgl_deinit_runtime when stopping running LVGL apps #134

Description

@From-summer-to-autumn

Checklist

  • Checked the issue tracker for similar issues to ensure this is not a duplicate
  • Read the documentation to confirm the issue is not addressed there and your configuration is set correctly
  • Tested with the latest version to ensure the issue hasn't been fixed

How often does this bug occurs?

often

Expected behavior

Stopping or replacing a running LVGL application (e.g., switching from one LVGL game to another) should cleanly tear down the current LVGL runtime and start the new one, without crashing.

Actual behavior (suspected bug)

When lua_lvgl_deinit_runtime() is called while an LVGL app is actively rendering, the device panics and reboots with a FreeRTOS assertion failure:

assert failed: vTaskPriorityDisinheritAfterTimeout tasks.c:5270 (pxTCB != pxCurrentTCBs[xPortGetCoreID()])

Root cause: in lua_lvgl_deinit_runtime() (lua_lvgl_runtime.c), lua_lvgl_quiesce_runtime() is called BEFORE lua_lvgl_stop_task(). At that point the LVGL render task (lua_lvgl_task) is still alive and also acquiring the same s_lvgl.mutex in its loop. Two tasks then contend on a priority-inheriting mutex taken with a timeout (xSemaphoreTake(s_lvgl.mutex, 1000ms) in lua_lvgl_lock), which under dual-core timing trips the kernel's priority-inheritance-disinherit assertion and panics.

I verified the latest version still has this order (quiesce before stop_task), so the issue is present on current code.

Possible fix: stop the LVGL task FIRST, then quiesce. Once the render task has exited (it releases the lock and self-deletes), the cleanup path is the sole holder of the mutex and there is no contention. Reordering to: stop tick timer -> lua_lvgl_stop_task() -> lua_lvgl_quiesce_runtime() resolves the crash. Tested locally; stopping/switching running LVGL apps repeatedly no longer crashes.

Error logs or terminal output

assert failed: vTaskPriorityDisinheritAfterTimeout tasks.c:5270 (pxTCB != pxCurrentTCBs[ xPortGetCoreID() ])

Backtrace: 0x403853dd:... 0x40389035:... 0x40385fbc:... 0x420c4f22:... 0x420c4f57:... 0x420c5011:... 0x420c50c9:...
--- 0x40389035: vTaskPriorityDisinheritAfterTimeout at FreeRTOS-Kernel/tasks.c:5270
--- 0x40385fbc: xQueueSemaphoreTake at FreeRTOS-Kernel/queue.c:1842
--- 0x420c4f22: lua_lvgl_lock at components/lua_modules/lua_module_lvgl/src/lua_lvgl_runtime.c:19
--- 0x420c4f57: lua_lvgl_quiesce_runtime at lua_lvgl_runtime.c:221
--- 0x420c5011: lua_lvgl_deinit_runtime at lua_lvgl_runtime.c:304
--- 0x420c50c9: lua_lvgl_deinit at lua_lvgl_runtime.c:519
--- 0x42112791: cap_lua_runtime_execute_file at cap_lua/src/cap_lua_runtime.c:448
--- 0x42113339: cap_lua_job_task at cap_lua/src/cap_lua_async.c:412

Rebooting...
rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)

Steps to reproduce the behavior

  1. Start an LVGL-based async task that renders continuously at high frequency (e.g., a game script that updates the UI every frame via lv_timer_handler).
  2. While the LVGL render task is actively running, trigger lua_lvgl_deinit() — e.g., stop the current LVGL job and start a new LVGL app
  3. The device panics and reboots within seconds.

Environment:
Hardware: ESP32-S3
ESP-IDF: v5.5.4
Component: lua_module_lvgl

Project release version

Cloned on June 18th

System architecture

ARM 32-bit (Raspberry Pi 32-bit)

Operating system

Windows

Operating system version

Windows 11

Shell

other (details in Additional context)

Additional context

Why it only triggers when stopping a running app: during normal operation only the render task uses s_lvgl.mutex (no contention). The race window opens the moment deinit is triggered while the render task is still looping — both tasks then contend on the timeout mutex for the first time.

This was discovered while using an on-device LLM agent to build LVGL games, where users frequently ask to "stop the current game and make a new one" while the previous game is still actively rendering — which consistently triggers the crash.

The fix is a small, localized reordering in lua_lvgl_deinit_runtime() (stop task before quiesce). Happy to open a PR if helpful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions