Bug 68496 - test-dbus-daemon crashes on wine
Summary: test-dbus-daemon crashes on wine
Status: RESOLVED DUPLICATE of bug 68852
Alias: None
Product: dbus
Classification: Unclassified
Component: GLib (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: Simon McVittie
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 54445
  Show dependency treegraph
 
Reported: 2013-08-24 09:44 UTC by Ralf Habacker
Modified: 2013-09-02 16:50 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments

Description Ralf Habacker 2013-08-24 09:44:22 UTC
Running test-dbus-daemon on wine using a cross compiled dbus build crashes in dbus-glib
The following backtrace shows that handler, which should be a pointer to IOHandler contains some like a string (the connection name ?), which fails in line 502. 

dbus 1.7.6 (git master)
dbus-glib 0.100 either from opensuse mingw32 package or self compiled using mingw32 cross compiler 

(gdb) bt
#0  0x67281e72 in connection_setup_new_from_old (context=context@entry=0x1501f8, old=0x14cf40) at dbus-gmain.c:502
#1  0x67281f13 in dbus_connection_setup_with_g_main (connection=0x14eaf0, context=0x1501f8) at dbus-gmain.c:556
#2  0x004019ab in connect_to_bus (address=0x14d280 "tcp:host=localhost,port=30912,family=ipv4,guid=5340eb0e38ac2973d70b87915217fc59")
    at /home/ralf/src/dbus/test/dbus-daemon.c:148
#3  0x00401bfc in setup (f=0x14d250, context=0x0) at /home/ralf/src/dbus/test/dbus-daemon.c:233
#4  0x68613697 in test_case_run (tc=0x13d030) at gtestutils.c:1713
#5  g_test_run_suite_internal (suite=suite@entry=0x13c010, path=<optimized out>, path@entry=0x68677d5d <__PRETTY_FUNCTION__.3097+265> "") at gtestutils.c:1767
#6  0x68613b79 in g_test_run_suite (suite=0x13c010) at gtestutils.c:1823
#7  0x68613bc0 in g_test_run () at gtestutils.c:1324
#8  0x00402dca in main (argc=1, argv=0x14b770) at /home/ralf/src/dbus/test/dbus-daemon.c:515
(gdb) l 500
495
496       cs = connection_setup_new (context, old->connection);
497
498       while (old->ios != NULL)
499         {
500           IOHandler *handler = old->ios->data;
501
502           connection_setup_add_watch (cs, handler->watch);
503           /* The old handler will be removed from old->ios as a side-effect */
504         }
(gdb) p old
$18 = (ConnectionSetup *) 0x14cf40
(gdb) p old->ios
$19 = (GSList *) 0x14e4a8
(gdb) p *old->ios
$20 = {data = 0x302e313a, next = 0x110000}
(gdb) p handler
$21 = (IOHandler *) 0x302e313a
(gdb) p *handler
Cannot access memory at address 0x302e313a
(gdb)
(gdb) x/s 0x14e4a8
0x14e4a8:       ":1.0"
Comment 1 Simon McVittie 2013-08-27 10:59:36 UTC
This might also be a dbus-glib bug.
Comment 2 Ralf Habacker 2013-08-27 12:49:49 UTC
(In reply to comment #1)
> This might also be a dbus-glib bug.

May depend on https://bugs.freedesktop.org/show_bug.cgi?id=35115 ?
Comment 3 Ralf Habacker 2013-08-29 04:52:31 UTC
(In reply to comment #0)
> Running test-dbus-daemon on wine using a cross compiled dbus build crashes
> in dbus-glib
> The following backtrace shows that handler, which should be a pointer to
> IOHandler contains some like a string (the connection name ?), which fails
> in line 502. 
> 
> dbus 1.7.6 (git master)
> dbus-glib 0.100 either from opensuse mingw32 package or self compiled using
> mingw32 cross compiler 
> 
> (gdb) bt
> #0  0x67281e72 in connection_setup_new_from_old
> (context=context@entry=0x1501f8, old=0x14cf40) at dbus-gmain.c:502
> #1  0x67281f13 in dbus_connection_setup_with_g_main (connection=0x14eaf0,
> context=0x1501f8) at dbus-gmain.c:556
> #2  0x004019ab in connect_to_bus (address=0x14d280
> "tcp:host=localhost,port=30912,family=ipv4,
> guid=5340eb0e38ac2973d70b87915217fc59")
>     at /home/ralf/src/dbus/test/dbus-daemon.c:148
> #3  0x00401bfc in setup (f=0x14d250, context=0x0) at
> /home/ralf/src/dbus/test/dbus-daemon.c:233
> #4  0x68613697 in test_case_run (tc=0x13d030) at gtestutils.c:1713
> #5  g_test_run_suite_internal (suite=suite@entry=0x13c010, path=<optimized
> out>, path@entry=0x68677d5d <__PRETTY_FUNCTION__.3097+265> "") at
> gtestutils.c:1767
> #6  0x68613b79 in g_test_run_suite (suite=0x13c010) at gtestutils.c:1823
> #7  0x68613bc0 in g_test_run () at gtestutils.c:1324
> #8  0x00402dca in main (argc=1, argv=0x14b770) at
> /home/ralf/src/dbus/test/dbus-daemon.c:515
> (gdb) l 500
> 495
> 496       cs = connection_setup_new (context, old->connection);
> 497
> 498       while (old->ios != NULL)
> 499         {
> 500           IOHandler *handler = old->ios->data;
> 501
> 502           connection_setup_add_watch (cs, handler->watch);
> 503           /* The old handler will be removed from old->ios as a
> side-effect */
> 504         }
> (gdb) p old
> $18 = (ConnectionSetup *) 0x14cf40
> (gdb) p old->ios
> $19 = (GSList *) 0x14e4a8
> (gdb) p *old->ios
> $20 = {data = 0x302e313a, next = 0x110000}
> (gdb) p handler
> $21 = (IOHandler *) 0x302e313a
> (gdb) p *handler
> Cannot access memory at address 0x302e313a
> (gdb)
> (gdb) x/s 0x14e4a8
> 0x14e4a8:       ":1.0"

The crash on this location did not happens when I remove the dbus_connection_get_data() call below. 

void
dbus_connection_setup_with_g_main (DBusConnection *connection,
				   GMainContext   *context)
{
  ConnectionSetup *old_setup;
  ConnectionSetup *cs;
  
  /* FIXME we never free the slot, so its refcount just keeps growing,
   * which is kind of broken.
   */
  dbus_connection_allocate_data_slot (&_dbus_gmain_connection_slot);
  if (_dbus_gmain_connection_slot < 0)
    goto nomem;

  if (context == NULL)
    context = g_main_context_default ();

  cs = NULL;
  old_setup = NULL;

  old_setup = dbus_connection_get_data (connection, _dbus_gmain_connection_slot);


560       old_setup = dbus_connection_get_data (connection, _dbus_gmain_connection_slot);
(gdb) n
562       if (old_setup != NULL)
(gdb) p old_setup 
$1 = (ConnectionSetup *) 0x14d128
(gdb) p *old_setup
$2 = {context = 0x14e260, ios = 0x14e820, timeouts = 0x0, connection = 0x4, message_queue_source = 0x0}
(gdb)

> connection = 0x4

this looks not valid.

Because dbus_connection_set_data() has not been called before in test-dbus-daemon this looks like an structure initialisation problem.
Comment 4 Simon McVittie 2013-08-29 09:45:08 UTC
(In reply to comment #3)
> Because dbus_connection_set_data() has not been called before in
> test-dbus-daemon this looks like an structure initialisation problem.

Hmm. I wonder why this worked for me, and has always worked on Linux?
Comment 5 Ralf Habacker 2013-08-29 23:19:28 UTC
(In reply to comment #4)
> (In reply to comment #3)
> > Because dbus_connection_set_data() has not been called before in
> > test-dbus-daemon this looks like an structure initialisation problem.
> 
> Hmm. I wonder why this worked for me, and has always worked on Linux?

I compiled debug dbus-glib and dbus on linux, run test-dbus-daemon under gdb with  breakpoints set on dbus_connection_get_data and  dbus_connection_set_data and here my research: 

------ [1] ensure_bus_data uses a connection data slot named bus_data_slot, which access is listed below 

/creds:
Breakpoint 3, dbus_connection_get_data (connection=0x14e218, slot=0) at /home/ralf/src/dbus/dbus/dbus-connection.c:5995
5995      _dbus_return_val_if_fail (connection != NULL, NULL);
(gdb) bt
#0  dbus_connection_get_data (connection=0x14e218, slot=0) at /home/ralf/src/dbus/dbus/dbus-connection.c:5995
#1  0x0041132e in ensure_bus_data (connection=0x14e218) at /home/ralf/src/dbus/dbus/dbus-bus.c:356

----- [2] the first calls return 0, which set's the data 

Breakpoint 2, dbus_connection_set_data (connection=0x14e218, slot=0, data=0x14d0e8, free_data_func=0x41124d <bus_data_free>) at /home/ralf/src/dbus/dbus/dbus-connection.c:5950
5950      _dbus_return_val_if_fail (connection != NULL, FALSE);
(gdb) bt
#0  dbus_connection_set_data (connection=0x14e218, slot=0, data=0x14d0e8, free_data_func=0x41124d <bus_data_free>) at /home/ralf/src/dbus/dbus/dbus-connection.c:5950
#1  0x0041138a in ensure_bus_data (connection=0x14e218) at /home/ralf/src/dbus/dbus/dbus-bus.c:368
... 
(gdb) c
Continuing.

----- [3] which is returned on the next ...get_data() call

Breakpoint 3, dbus_connection_get_data (connection=0x14e218, slot=0) at /home/ralf/src/dbus/dbus/dbus-connection.c:5995
5995      _dbus_return_val_if_fail (connection != NULL, NULL);
(gdb) bt
#0  dbus_connection_get_data (connection=0x14e218, slot=0) at /home/ralf/src/dbus/dbus/dbus-connection.c:5995
#1  0x0041132e in ensure_bus_data (connection=0x14e218) at /home/ralf/src/dbus/dbus/dbus-bus.c:356
(gdb)

------ The returned data array is of type BusData 

357       if (bd == NULL)
(gdb) p bd
$8 = (BusData *) 0x14d0e8

with the content 

[4] 
(gdb) p *bd
$9 = {connection = 0x14e218, unique_name = 0x14e800 ":1.11", is_well_known = 0}
(gdb)

------- [5] in dbus-glib there is another connection data slot used named _dbus_gmain_connection_slot

Please note that this is the same connection address

Breakpoint 3, dbus_connection_get_data (connection=0x14e218, slot=0) at ../../dbus/dbus/dbus-connection.c:5992
5992    {
(gdb) bt 
#0  dbus_connection_get_data (connection=0x14e218, slot=0) at ../../dbus/dbus/dbus-connection.c:5992
#1  0x67281f4a in dbus_connection_setup_with_g_main (connection=0x14e218, context=0x150050) at ../../dbus-glib/dbus/dbus-gmain.c:560
...

(gdb) n
5995      _dbus_return_val_if_fail (connection != NULL, NULL);
(gdb)
5996      _dbus_return_val_if_fail (slot >= 0, NULL);
(gdb)
5998      SLOTS_LOCK (connection);
(gdb)
6000      res = _dbus_data_slot_list_get (&slot_allocator,
(gdb)
6004      SLOTS_UNLOCK (connection);
(gdb)
6006      return res;
(gdb)
6007    }
(gdb)    
dbus_connection_setup_with_g_main (connection=0x14e218, context=0x150050) at ../../dbus-glib/dbus/dbus-gmain.c:562
562       if (old_setup != NULL)

---------  the data slot is returned in old_setup 

(gdb) p old_setup
$1 = (ConnectionSetup *) 0x14d0e8
(gdb)

------ Please note that this is the same address of the above mentioned BusData instance [4]  ($8 = (BusData *) 0x14d0e8)

------ Now see the content of dbus-glib defined  data slot instance: 

(gdb) p *old_setup 
$3 = {context = 0x14e218, ios = 0x14e800, timeouts = 0x0, connection = 0x4, message_queue_source = 0x0}
(gdb)

------ compared to the data slot content mentioned at [4] 
n
$9 = {connection = 0x14e218, unique_name = 0x14e800 ":1.11", is_well_known = 0}

------  you can see that the first two members are bu addresses, which explains the initial mentioned connection string value. 


Results: The  get_data call [5] is the first one using slot _dbus_gmain_connection_slot so it should return 0, instead it returns the data from the bus_data_slot used in ensure_bus_data() [4]

In the opposite on linux

------  the data slot used in ensure_bus_data() is number 0

Breakpoint 1, dbus_connection_get_data (connection=0x609880, slot=0) at ../../dbus/dbus/dbus-connection.c:5995
5995      _dbus_return_val_if_fail (connection != NULL, NULL);


------- and in  dbus_connection_setup_with_g_main() is 1 

#0  dbus_connection_get_data (connection=0x609880, slot=1) at ../../dbus/dbus/dbus-connection.c:5995
#1  0x00007ffff7868145 in dbus_connection_setup_with_g_main (connection=0x609880, context=0x60c5a0) at ../../dbus-glib/dbus/dbus-gmain.c:560

------- which avoids the collision. 

But why are the slots the same on windows - it turns out, that dbus-glib uses a shared dbus-1 library and test-dbus-daemon  dbus-internal which is static and therefore uses separate instance data, which let the slot allocator fail to increment the slot numbers. 

<offtopic> 
Additional autotools dbus build (which i used to build glib and dbus-glib) cross compiled the dbus library as libdbus-1-3.dll. 
cmake - because of historical reasons - take libdbus-1d.dll for debug builds and libdbus-1.dll for release builds, so cmake cross-compiled dbus-daemon uses a third library instance beside the mentioned two. 
-> need to be fixed 
</offtopic>
Comment 6 Ralf Habacker 2013-08-29 23:28:22 UTC
(In reply to comment #5)
> (In reply to comment #4)
> > (In reply to comment #3)
> > > Because dbus_connection_set_data() has not been called before in
> > > test-dbus-daemon this looks like an structure initialisation problem.
> > 
> > Hmm. I wonder why this worked for me, and has always worked on Linux?
> 
...
> But why are the slots the same on windows - it turns out, that dbus-glib
> uses a shared dbus-1 library and test-dbus-daemon  dbus-internal which is
> static and therefore uses separate instance data, which let the slot
> allocator fail to increment the slot numbers. 

In fact i let test-dbus-daemon also use the shared dbus-1 library, which solve the problem, but then we do not have _dbus_getsid() by default. 
e t
May be we can add those functions statically or by a shared dbus-1-<extra> or <internal> or similar named library, containing all the stuff not in dbus-1. 

This would mean that dbus-daemon, the test apps and may be some tools would have two shared library dependencies: dbus-1 and dbus-1-<extra>
Comment 7 Simon McVittie 2013-08-30 12:59:50 UTC
(In reply to comment #5)
> But why are the slots the same on windows - it turns out, that dbus-glib
> uses a shared dbus-1 library and test-dbus-daemon  dbus-internal which is
> static and therefore uses separate instance data, which let the slot
> allocator fail to increment the slot numbers. 

Good catch... I'll look into sorting that out.

I would prefer to keep any tests that do not need _dbus* symbols using the shared libdbus-1, because that means we can run them on an installed system as an integration test (see <https://wiki.gnome.org/GnomeGoals/InstalledTests> and our own Bug #34570).

This probably means I should split out the 'creds' test from test-dbus-daemon.c to a separate source file or something. Having done that, we can link it to dbus-internal and make it use DBusLoop instead of dbus-glib (at least on Windows, but to make life easier, probably everywhere).
Comment 8 Simon McVittie 2013-08-30 13:04:06 UTC
(In reply to comment #6)
> May be we can add those functions statically or by a shared dbus-1-<extra>
> or <internal> or similar named library, containing all the stuff not in
> dbus-1. 

The problem is that we have a circular dependency. The dependency stack goes something like this:

    _dbus_foo ("high level") -> dbus_foo -> _dbus_foo ("low level")
       dbus-internal             both        both

(where "both" means there is one copy in dbus-1 and one in dbus-internal).

I don't really want to split out a second (low level) shared library, containing no public symbols, for use only by dbus-1 and the tools. In practice, I'm concerned that everyone would start using symbols from the low level library and we'd be stuck with it as API, which limits our ability to fix bugs by forcing us to care about backwards compatibility. Having a second shared library also means the linker has to do more work during startup.
Comment 9 Simon McVittie 2013-09-02 16:50:42 UTC
(In reply to comment #7)
> we can link it to dbus-internal and make it use DBusLoop instead of
> dbus-glib (at least on Windows, but to make life easier, probably
> everywhere).

See Bug #68852.

Closing this one as a dup of that.

*** This bug has been marked as a duplicate of bug 68852 ***


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.