Created attachment 121657 [details] dbus-test.c It seems dbus_connection_open() is not returning shared connections. It is not clear if there is some miss configuration or some bug. The issue can be seen easily. Every call to dbus_connection_open() returns a different pointer and refcount of 2 (1 for application and 1 for libdbus). After some time the system is crashing because the connections are maxed out. There are dbus_connection_unref() calls but this doesn't free the shared connections and since we are getting a new connection every time, it is easy to max them out. We checked the resources usage and the number of FDs, sockets and memory increase with every call. After some investigation, dbus_bus_get() seems to always return the same pointer with refcount incremented as expected. FDs, sockets, memory seem not impacted. Attached is a simple program tested on x86 ubuntu that shows this behavior.
(In reply to missa from comment #0) > After some investigation, dbus_bus_get() seems to always return the same > pointer with refcount incremented as expected. If you are connecting to the standard system or session bus, I would recommend using dbus_bus_get() - that's what it's there for. If your application requires a connection to a custom bus or peer-to-peer server specified by its address, then dbus_connection_open() is the correct function to be using, and you are correct to think that for (...) { conn = dbus_connection_open (address, &error); dbus_connection_unref (conn); } should return the same pointer repeatedly. You could work around this bug by calling dbus_connection_open() (or dbus_connection_open_private()) once, and storing the resulting pointer in your own global or static variable. That's essentially what libdbus has to do for dbus_bus_get(), and what it's meant to do for dbus_connection_open() (but from your report it seems that the latter doesn't work correctly). I suspect that the reason nobody previously reported this is that most libdbus users use dbus_bus_get(), and in use-cases that need to connect to a specified address (for example the Tubes APIs in Telepathy), the implementer usually doesn't want the connection-sharing behaviour and will use dbus_connection_open_private().
(In reply to Simon McVittie from comment #1) > (but from your report it seems that the latter doesn't work correctly) I couldn't reproduce this with the current stable release of libdbus (1.10.6 from the Debian package libdbus-1-3 version 1.10.6-1), after changing the value of "n" to be getenv ("DBUS_SESSION_BUS_ADDRESS") so your test program works on systems other than your own. I get the same connection repeatedly, with a refcount that goes up every time, or stays at 2 if I uncomment the dbus_connection_unref() call. (In reply to missa from comment #0) > tested on x86 ubuntu What does "x86 ubuntu" mean? i386 or x86_64? Which version of Ubuntu? Which version of libdbus-1-3?
Created attachment 121673 [details] [review] Add a regression test for connection re-use Loosely based on loopback.c. This was an attempt to reproduce bug 94085.
We do have a custom bus. The issue is first reported on ARM with libdbus 1.6.4 We reproduced on latest ubuntu 15.10-desktop-amd64 x86_64. missa@ubuntu:~/Desktop/dbus$ uname -a Linux ubuntu 4.2.0-27-generic #32-Ubuntu SMP Fri Jan 22 04:49:08 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux missa@ubuntu:~/Desktop/dbus$ dbus-daemon --version D-Bus Message Bus Daemon 1.10.0 Copyright (C) 2002, 2003 Red Hat, Inc., CodeFactory AB, and others This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. I tried to change "n" as you suggested but we get the same results: Trial 0 conn ptr 0xc77df0 refcount 2 Trial 1 conn ptr 0xc78a20 refcount 2 Trial 2 conn ptr 0xc79650 refcount 2 Trial 3 conn ptr 0xc7a280 refcount 2 Trial 4 conn ptr 0xc7b1d0 refcount 2 Trial 5 conn ptr 0xc7be00 refcount 2 Trial 6 conn ptr 0xc7ca30 refcount 2 Trial 7 conn ptr 0xc7d660 refcount 2 Trial 8 conn ptr 0xc7e290 refcount 2 Trial 9 conn ptr 0xc7eec0 refcount 2
Using this library: ls -l /usr/lib/x86_64-linux-gnu/libdbus-1.so lrwxrwxrwx 1 root root 41 Sep 1 10:01 /usr/lib/x86_64-linux-gnu/libdbus-1.so -> /lib/x86_64-linux-gnu/libdbus-1.so.3.14.3
Thanks, I can reproduce this on Ubuntu with libdbus-1-3 version 1.10.0-1ubuntu1. (When reporting bugs in Debian or Ubuntu packages, please use "dpkg -s libdbus-1-3" or "dpkg-query -W libdbus-1-3" to find the exact version number.) The difference appears to be in the Ubuntu-specific script that starts the session dbus-daemon via Upstart: it produces a DBUS_SESSION_BUS_ADDRESS that does not include the 'guid' parameter. The same thing happens with dbus started by a systemd user session, for which the value is something like "unix:path=/run/user/1000/bus". However, it does not happen under "dbus-run-session ./dbus-test", which creates a temporary bus address and gives it to dbus-test; that address does include the guid. For your custom bus, if you obtained the address from the DBusServer: /* if using a DBusServer directly */ const char *address = dbus_server_get_address (server); DBusConnection *shared_conn = dbus_connection_open (address, &error); # if using dbus-daemon dbus-daemon --print-address=1 > address.txt # or a higher fd if stdout is in use for something else dbus-daemon --print-address=5 5> address.txt # or from C/C++ code, use the fd of a pipe, like in # tools/dbus-run-session.c and test/test-utils-glib.c then it would contain the guid and dbus_connection_open() would work as intended. dbus_connection_open() uses the guid to identify what is "the same" connection, because in principle there could be address types for which connecting to the same string address results in a connection to a logically different bus. You might think that this can be fixed by using simple string comparison of addresses when deciding what is "the same bus", but that just makes the problem rarer, and does not eliminate it. For example, these addresses: tcp:host=localhost,port=1234 tcp:port=1234,host=localhost tcp:port=1234,host=127.0.0.1 are all equivalent (on an IPv4 system), but a simple string comparison would not reflect this. I think we should deprecate dbus_connection_open(), add a note about this limitation to its documentation, and recommend that anyone wanting to cache private connections uses their own global or static variable (Comment #1).
Thanks for your input! I guess the only way is to get it using the --print-address. These details about guid are useful for the API documentation for dbus_connection_open(). Maybe the API should also fail if a guid is not supplied. Otherwise, users will leak resources and get unexpected outputs.
-- GitLab Migration Automatic Message -- This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/dbus/dbus/issues/144.
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.