diwic / dbus-rs

D-Bus binding for the Rust language
Other
592 stars 133 forks source link

Crashes in `dbus::blocking::Connection::new_session` #486

Open FractalFir opened 1 month ago

FractalFir commented 1 month ago

Hi! Recently, I have been trying to fix a crashing issue in a library(xcap) which uses dbus-rs under the hood.

After a lot of investigation, it looks like the crashes happen in dbus::blocking::Connection::new_session.

Thread 101 "tokio-runtime-w" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffc9200680 (LWP 43046)]
0x0000555558ae682a in _dbus_transport_do_iteration (transport=0x7ffe74001000, flags=flags@entry=1, timeout_milliseconds=-268435713, timeout_milliseconds@entry=-2) at ./vendor/dbus/dbus/dbus-transport.c:1013
1013      (* transport->vtable->do_iteration) (transport, flags,
(gdb) bt
#0  0x0000555558ae682a in _dbus_transport_do_iteration (transport=0x7ffe74001000, flags=flags@entry=1, timeout_milliseconds=-268435713, timeout_milliseconds@entry=-2) at ./vendor/dbus/dbus/dbus-transport.c:1013
#1  0x0000555558ad81e8 in _dbus_connection_do_iteration_unlocked (connection=connection@entry=0x7ffe740017c0, pending=pending@entry=0x0, flags=flags@entry=1, timeout_milliseconds=-2, timeout_milliseconds@entry=-1) at ./vendor/dbus/dbus/dbus-connection.c:1227
#2  0x0000555558ad8276 in _dbus_connection_send_preallocated_unlocked_no_update (connection=connection@entry=0x7ffe740017c0, preallocated=0x0, message=message@entry=0x7ffe04004a00, client_serial=client_serial@entry=0x0)
    at ./vendor/dbus/dbus/dbus-connection.c:2057
#3  0x0000555558ad82df in _dbus_connection_send_unlocked_no_update (connection=connection@entry=0x7ffe740017c0, message=message@entry=0x7ffe04004a00, client_serial=client_serial@entry=0x0) at ./vendor/dbus/dbus/dbus-connection.c:3266
#4  0x0000555558ad8f27 in dbus_connection_send_with_reply (connection=connection@entry=0x7ffe740017c0, message=message@entry=0x7ffe04004a00, pending_return=pending_return@entry=0x7fffc91f9118, timeout_milliseconds=timeout_milliseconds@entry=-1)
    at ./vendor/dbus/dbus/dbus-connection.c:3467
#5  0x0000555558ad901e in dbus_connection_send_with_reply_and_block (connection=connection@entry=0x7ffe740017c0, message=message@entry=0x7ffe04004a00, timeout_milliseconds=timeout_milliseconds@entry=-1, error=error@entry=0x7fffc91f9238)
    at ./vendor/dbus/dbus/dbus-connection.c:3561
#6  0x0000555558ad2cee in dbus_bus_register (connection=connection@entry=0x7ffe740017c0, error=error@entry=0x7fffc91f9238) at ./vendor/dbus/dbus/dbus-bus.c:696
#7  0x0000555558ad2e68 in internal_bus_get (type=DBUS_BUS_SESSION, private=private@entry=1, error=0x7fffc91f9238) at ./vendor/dbus/dbus/dbus-bus.c:484
#8  0x0000555558ad2ff8 in dbus_bus_get_private (type=<optimized out>, error=<optimized out>) at ./vendor/dbus/dbus/dbus-bus.c:594
#9  0x0000555558aa171c in dbus::channel::ffichannel::Channel::get_private (bus=dbus::channel::BusType::Session) at src/channel/ffichannel.rs:157
#10 0x0000555558acd9b3 in dbus::blocking::Connection::new_session () at src/blocking.rs:145
#11 0x0000555558932d1c in xcap::platform::wayland_capture::wayland_capture (impl_monitor=0x7ffe10002378) at src/linux/wayland_capture.rs:176
#12 0x000055555897a4ae in xcap::platform::capture::capture_monitor (impl_monitor=0x7ffe10002378) at src/linux/capture.rs:27
#13 0x00005555589ba676 in xcap::platform::impl_monitor::ImplMonitor::capture_image (self=0x7ffe10002378) at src/linux/impl_monitor.rs:237
#14 0x00005555588ff536 in xcap::monitor::Monitor::capture_image (self=0x7ffe10002378) at src/monitor.rs:79

I am using this function in a multi-threaded context, but I use locks to grantee only one thread uses dbus-rs at any given time.

Since Connection::new_session is a safe function, I'd expect there to be no special requirements. The documentation of dbus-rs and Connection::new_session also does not say anything about any safety additional requirements.

Is this a known issue? If so, are there any workarounds?

diwic commented 1 month ago

Never seen anything like this in a very long time. It could be a bug in the C library code.

What version of libdbus are you using? Does upgrading/downgrading it help?

FractalFir commented 1 month ago

I was using using dbus = { version = "0.9", features = ["vendored"] }, I updated to dbus = { version = "0.9.7", features = ["vendored"] }, but that did not help.

How do i check which version of libdbus is used with vendored?

Bizarrely, switching to a system version of libdbus seems to work just fine. I am running

Linux fedora 6.10.11-200.fc40.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Sep 18 21:09:58 UTC 2024 x86_64 GNU/Linux

and the libdbus version is 1:1.14.10-3.fc40(according to my package manager).

Normally, the crashes occur after a few seconds, but I have been taking a screenshot every second for 4 minutes straight, and it seems to run just fine, without any crashes or lost messages(which is something I sometimes encountered before).

Is there any other info you might need?

diwic commented 1 month ago

@FractalFir

Thanks for the investigation. So it only happens when vendored is enabled.

It's totally possible that it is a bug in 1.14.4 (what vendored currently uses) that is fixed in 1.14.10 (which your system uses). There is also a warning somewhere in the docs saying that the recommended way is to build a separate .so and building it into the executable (which we do) is unsupported. So it might be something related to that as well.

Just speculating, this is code we just pull in and build, and that somehow causes a segfault for you.