Bug 47060 - Segfault with parallel calls to dbus_bus_get_private
Summary: Segfault with parallel calls to dbus_bus_get_private
Status: RESOLVED INVALID
Alias: None
Product: dbus
Classification: Unclassified
Component: core (show other bugs)
Version: 1.4.x
Hardware: Other Linux (All)
: medium major
Assignee: Havoc Pennington
QA Contact: John (J5) Palmieri
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-07 08:33 UTC by David Henningsson
Modified: 2012-03-12 16:15 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments
Test case (627 bytes, text/x-csrc)
2012-03-07 08:33 UTC, David Henningsson
Details

Description David Henningsson 2012-03-07 08:33:07 UTC
Created attachment 58126 [details]
Test case

From what I've been taught by Lennart, and what PulseAudio does, is that calling dbus_bus_get_private in several threads in parallel is correct. However doing so results in a segfault. 

I'm attaching a test case for reference.
Comment 1 Simon McVittie 2012-03-12 05:12:24 UTC
(In reply to comment #0)
> From what I've been taught by Lennart, and what PulseAudio does, is that
> calling dbus_bus_get_private in several threads in parallel is correct. However
> doing so results in a segfault. 

What version of dbus are you using? There is known multi-threading breakage on Unix in all releases older than 1.5.10, a long-standing bug present since 2006 (Bug #43744).
Comment 2 David Henningsson 2012-03-12 05:22:42 UTC
Ok, thanks for the reply.
 
I'm using 1.4.18. Do you know if there is a fix available/planned for the 1.4 series?
Comment 3 Simon McVittie 2012-03-12 06:06:08 UTC
(In reply to comment #2)
> Do you know if there is a fix available/planned for the 1.4 series?

Maybe... I can backport the changes to 1.4.x (and I need to do that soon anyway, for an embedded distro with a 1.4.x fork), but they're more intrusive than I'd really like to apply to a supposed stable branch. If they were less intrusive I'd have developed against 1.4.x to start with.

If you could try your test case with 1.5.10 (e.g. from Debian experimental), that would be very useful. I notice you have a Canonical e-mail address, so you're probably using Ubuntu? If so, you might not be able to use 1.5.10 installed system-wide without merging Ubuntu's Upstart-integration changes (probably not at all trivial), but it should still be possible to build 1.5.10 locally and link your test case against the libdbus-1.so.3 that it produces.

I'm hoping to get a 1.6.x new-stable branch out sometime soon, but there's still a backlog of changes that should get into in 1.6.x, which need code review (I can't review most of them myself, because I wrote them).
Comment 4 David Henningsson 2012-03-12 08:14:29 UTC
Hi,

It seems the problem is present in 1.5.10 as well. Perhaps you can reproduce by running the test case on your installation? It should be really simple to compile ( gcc dbus-test.c $(pkg-config --libs --cflags dbus-1) ).

I did the following (in Ubuntu 12.04, currently in beta) :

* sudo apt-get builddep dbus
* Downloaded 1.5.10, configure, make
* export LD_LIBRARY_PATH=$(pwd)/dbus/.libs
* ran the test case, which fails sometimes with SIGSEGV and sometimes with glibc "double free or corruption" errors.
Comment 5 Simon McVittie 2012-03-12 11:12:43 UTC
Now that I look at your test case... you're not telling libdbus to use mutexes, so it won't be thread-safe at all. You need something like this:

    if (!dbus_threads_init_default ())
        {
            fprintf (stderr, "Unable to initialize threads (out of memory?)");
            exit (1);
        }

(or replace with your favourite way to handle fatal errors).

Annoyingly, libdbus can't be thread-safe-by-default without incompatible changes. Mutex setup requires memory to be allocated, at least on some platforms, so it can fail (on OOM), and we need to handle that somehow. libdbus policy is to not crash on OOM, so we can't do that - but some functions that are implemented with mutexes have no way to report OOM, so we can't initialize threads lazily and report OOM if it fails.

>     while (!quit) {

This is not reliable in a multi-threaded environment either, FWIW. Use an atomic variable or a mutex if you need two threads to communicate.
Comment 6 David Henningsson 2012-03-12 16:15:17 UTC
Indeed we seem to miss dbus_threads_init_default in both the test case and in PulseAudio. I will fix that, and report back in case that does not resolve our crashes.

Thanks for the advice!


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.