Every Application now runs a HangWatchdog from start() to finish(). The main loop marks its phase (idle, input, draw, present); when the UI thread stays in a non-idle phase past a threshold (2 s), a watchdog thread writes a report folder to the per-user state directory: $XDG_STATE_HOME/modules/hangs/<app>-<date>-build<rev>/, overridable with MODULES_HANG_DIR, keeping the newest 20 reports. summary.txt names the stuck phase, the chain of open TP_PROFILE_SCOPE sections on the UI thread and a verdict: blocked at one place (with the kernel wait channel), busy running, or waiting at changing places. threads.txt holds five samples of every thread's stack. Follow-ups at 10 s and 30 s are appended, and recovery is noted when the UI thread moves on. Applications add their own files through hang contributors; Sketch2D writes engine queue state, read with try-lock so a report never waits on the lock the UI may be stuck behind. Architecture: the UI scope trail is a lock-free stack in Modules fed by ProfileScope, so it works with the profiler off. Callstack gains StackTrace, the single place for capturing a stack into a caller buffer, naming frames with dladdr, and sampling all threads through a real-time signal; CallStackCapture is rebuilt on it, removing the addr2line subprocess. The watchdog lives in a new Diagnostics library above both. The process also allows any same-user debugger to attach, so gdb -p or eu-stack work on a frozen window. Debug > Simulate hang (5 s) exercises the whole path in the app.
16 lines
658 B
CMake
16 lines
658 B
CMake
project(Diagnostics)
|
|
|
|
### ---------------------- Static Library --------------------- ###
|
|
file(GLOB SOURCES CONFIGURE_DEPENDS "./private/*.cpp")
|
|
|
|
add_library(${PROJECT_NAME} STATIC ${SOURCES})
|
|
target_include_directories(${PROJECT_NAME} PUBLIC ./public/)
|
|
target_link_libraries(${PROJECT_NAME} PUBLIC Modules Callstack)
|
|
|
|
### -------------------------- Tests -------------------------- ###
|
|
if (MODULES_BUILD_TESTS)
|
|
file(GLOB TEST_SOURCES "./tests/*.cpp")
|
|
add_executable(Tests${PROJECT_NAME} ${TEST_SOURCES})
|
|
target_link_libraries(Tests${PROJECT_NAME} ${PROJECT_NAME} UnitTest++)
|
|
add_test(NAME Tests${PROJECT_NAME} COMMAND Tests${PROJECT_NAME})
|
|
endif ()
|