-
-
Notifications
You must be signed in to change notification settings - Fork 64
SIGSEGV in rpt_lsof_collect0 during suspend resume #596
Description
FYI, I generated this report using AI. I got this crash while on 2.2.7-DEV (specific commit mentioned below).
Summary
powerdevil (KDE Power Management) crashes with SIGSEGV when resuming from suspend (opening laptop lid). The crash is in ddcutil 2.2.7-DEV's new open-failure diagnostic code path, specifically a null pointer dereference in rpt_lsof_collect0.
Environment
- OS: Arch Linux (x86_64)
- Kernel: 6.18.6
- Wayland compositor: KWin 6.6.3
- GPU: AMD (amdgpu, DCN 3.5.1)
- ddcutil: 2.2.7-DEV (built from master branch, commit d7c0379)
- powerdevil: 6.6.3
Trigger
Opening the laptop lid to resume from suspend. The laptop's eDP display generates I2C bus change events during resume. ddcutil's watch thread detects the screen change and attempts to re-enumerate I2C buses, but one bus is transiently unavailable. The open fails, and the new diagnostic code crashes while trying to log the failure.
Crash details
- Signal: 11 (SIGSEGV)
- Faulting instruction:
mov 0x8(%rax),%edxat offset 0x7f0f9 in libddcutil.so.5 (rpt_lsof_collect0), where%raxis null/invalid
Stack trace (crashing thread)
Symbols resolved via addr2line against the unstripped build of libddcutil.so.5.5.0:
#0 __pthread_kill_implementation (pthread_kill.c:44)
#1 __pthread_kill_internal (pthread_kill.c:89)
#2 __GI_raise (raise.c:26)
#3 KCrash::defaultCrashHandler (kcrash.cpp:623)
#4 <signal handler called>
#5 rpt_lsof_collect0 <-- SIGSEGV here (null pointer dereference)
#6 diagnose_open_failure_collect
#7 diagnose_open_failure_to_syslog
#8 i2c_open_bus_basic <-- I2C bus open failed, entered diagnostic path
#9 i2c_open_bus
#10 i2c_edid_exists
#11 i2c_filter_buses_w_edid_as_bitset
#12 process_screen_change_event <-- ddcutil watch detected screen change (dw_poll.c)
#13 dw_watch_display_connections <-- ddcutil display watch thread
#14 dw_recheck_displays_func <-- ddcutil recheck thread entry
#15 g_thread_proxy (gthread.c:893) <-- glib thread pool
Other threads at time of crash
- Main thread (237773): idle in QCoreApplication::exec() event loop
- Thread 237815: ddcutil recheck thread waiting in g_async_queue_timeout_pop (normal idle state)
- Thread 237780: glib worker thread (g_main_context_iteration)
- Threads 237777, 237778: Qt Wayland client threads (poll)
- Thread 237774: Qt DBus thread
- Thread 237781: GIO D-Bus shared thread
- Thread 237779: glib thread pool (g_async_queue_pop, idle)
Analysis
The crash is in the new open-failure diagnostic functions added in the recent commits:
d14ab57 i2c_open_bus_basic(): use diagnose open_failure_to_syslog() if error4815b1a add and modify functions for diagnosing unexpected open() failure
When i2c_open_bus_basic() fails to open an I2C bus (which is expected during suspend/resume when buses are transiently unavailable), it calls diagnose_open_failure_to_syslog(), which calls diagnose_open_failure_collect(), which calls rpt_lsof_collect0(). The rpt_lsof_collect0 function dereferences a pointer at offset +8 that is null, causing the SEGV.
The I2C bus open failure itself is benign (transient unavailability during resume). The crash is in the diagnostic/logging code that handles the failure, not in the core detection logic.
Attachments
- Crash trace: powerdevil_20260331.txt
- GDB backtrace (debuginfod-resolved symbols for libc/glib/KCrash): gdb-debuginfod-output.txt
- Unstripped libddcutil build from commit d7c0379, for symbol resolution: libddcutil.so.5.5.0.gz
- Coredump: core.org_kde_powerde.1000.4e8ab4a77bff4ddcb823fc3f3ef6527e.237773.1774968497000000.gz
To resolve ddcutil symbols against the provided unstripped library, use addr2line with offsets relative to the libddcutil.so.5 base address (0x7f14faed0000 in this core):
addr2line -e libddcutil.so.5.5.0 -f -C -p 0x7f0f9 0x7f2bf 0x7f30e 0x30381 0x3081d 0x34fe7 0x36d97 0x91003 0x92278
This report was generated with AI assistance (Claude Opus 4.6, Anthropic).