Change bus connection check code : bus_connection_is_active () ==> dbus_connection_ge... 06/117406/4 accepted/tizen/common/20170320.173720 accepted/tizen/ivi/20170320.222436 accepted/tizen/mobile/20170320.222346 accepted/tizen/tv/20170320.222401 accepted/tizen/unified/20170320.222501 accepted/tizen/wearable/20170320.222419 submit/tizen/20170320.071222
authorINSUN PYO <insun.pyo@samsung.com>
Sun, 5 Mar 2017 00:30:23 +0000 (09:30 +0900)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Mon, 20 Mar 2017 06:40:23 +0000 (23:40 -0700)
Since dbus-daemon uses asynchronous cynara functions, some cynara functions are delayed.
In the cynara delay function, check if connection is valid or not.

If the connection is lost, the "connection->slot_list" is cleared. So bus_connection_is_active() will cause crash.
Since dbus_connection_get_is_connected() only checks for "connection->transport->disconnected" variables, it works fine if only the reference count is valid.

====================================================================================================================================
0  bus_connection_is_active (connection=<optimized out>) at connection.c:1291
1  0xb6f08134 in bus_deferred_message_dispatch (deferred_message=0xb7c93668) at check.c:498
2  0xb6f0c7ce in bus_connection_dispatch_deferred (connection=0xb7ca0008) at connection.c:2677
3  0xb6f0826a in bus_check_queued_message_reply_callback (deferred_message=0xb7cb5870, result=<optimized out>) at check.c:188
4  0xb6f0cdda in bus_cynara_check_response_callback (check_id=<optimized out>, cause=<optimized out>, response=<optimized out>, user_response_data=0xb7cb5870) at cynara.c:333
5  0xb6db2994 in Cynara::Logic::processCheckResponse (this=this@entry=0xb7c0cdb8, checkResponse=...) at /usr/src/debug/cynara-0.14.7/src/client-async/logic/Logic.cpp:277
6  0xb6db3a8e in Cynara::Logic::processResponses (this=this@entry=0xb7c0cdb8) at /usr/src/debug/cynara-0.14.7/src/client-async/logic/Logic.cpp:324
7  0xb6db4578 in Cynara::Logic::processIn (this=this@entry=0xb7c0cdb8) at /usr/src/debug/cynara-0.14.7/src/client-async/logic/Logic.cpp:348
8  0xb6db45d8 in Cynara::Logic::process (this=0xb7c0cdb8) at /usr/src/debug/cynara-0.14.7/src/client-async/logic/Logic.cpp:175
9  0xb6daf35a in operator() (this=<optimized out>) at /usr/lib/gcc/armv7l-tizen-linux-gnueabi/4.9.2/include/c++/functional:2439
10 Cynara::tryCatch(std::function<int ()> const&) (func=...) at /usr/src/debug/cynara-0.14.7/src/common/exceptions/TryCatch.h:42
11 0xb6dafa5e in cynara_async_process (p_cynara=0xb7c0c7a0) at /usr/src/debug/cynara-0.14.7/src/client-async/api/client-async-api.cpp:236
12 0xb6f0cdb4 in bus_cynara_watch_callback (watch=<optimized out>, flags=<optimized out>, data=<optimized out>) at cynara.c:288
13 0xb6f14f5a in _dbus_loop_iterate (loop=loop@entry=0xb7c0b618, block=block@entry=1) at dbus-mainloop.c:819
14 0xb6f1506c in _dbus_loop_run (loop=0xb7c0b618) at dbus-mainloop.c:883
15 0xb6f046f6 in main (argc=<optimized out>, argv=<optimized out>) at main.c:661

(gdb) info locals
d = 0x0

(gdb) f 1

(gdb) p *deferred_message->sender
$27 = {refcount = {value = 1}, mutex = 0xb7c41c70, dispatch_mutex = 0xb7c41cb0, dispatch_cond = 0xb7c41cd0, io_path_mutex = 0xb7c41c90, io_path_cond = 0xb7c41d08, outgoing_messages = 0x0, incoming_messages = 0x0, expired_messages = 0x0, message_borrowed = 0x0,
  n_outgoing = 0, n_incoming = 0, outgoing_counter = 0xb7c41df8, transport = 0xb7c41778, watches = 0xb7c41b20, timeouts = 0xb7c41b40, filter_list = 0x0, slot_mutex = 0xb7c41d40, slot_list = {slots = 0xb7c41fc0, n_slots = 1}, pending_replies = 0xb7c41b60,
  client_serial = 10, disconnect_message_link = 0x0, wakeup_main_function = 0x0, wakeup_main_data = 0x0, free_wakeup_main_data = 0x0, dispatch_status_function = 0x0, dispatch_status_data = 0x0, free_dispatch_status_data = 0x0, last_dispatch_status = DBUS_DISPATCH_COMPLETE,
  objects = 0xb7c41f20, server_guid = 0x0, peer_smack_label = 0xb7c41c60 "System", dispatch_acquired = 0, io_path_acquired = 0, dispatch_disabled = 0, shareable = 0, exit_on_disconnect = 0, route_peer_messages = 1, disconnected_message_arrived = 1,
  disconnected_message_processed = 1, have_connection_lock = 0, generation = 1}

(gdb) p deferred_message->sender->slot_list
$28 = {slots = 0xb7c41fc0, n_slots = 1}

(gdb) p *deferred_message->sender->slot_list->slots
$31 = {data = 0x0, free_data_func = 0x0}

(gdb) p connection_data_slot
$32 = 0

(gdb) p deferred_message->sender->slot_list->slots[0]
$35 = {data = 0x0, free_data_func = 0x0}

(gdb) p deferred_message->sender->transport->disconnected
$33 = 1
====================================================================================================================================

Signed-off-by: INSUN PYO <insun.pyo@samsung.com>
Change-Id: Iab2abfb63030d15e380e11c057ee1f99124e102e
(cherry picked from commit 62fd017b7dbf577f736de7f8d44e6a94b4334472)

bus/check.c

index a859fac..9bbca63 100644 (file)
@@ -146,7 +146,8 @@ bus_check_queued_message_reply_callback (BusDeferredMessage *deferred_message,
 
   _dbus_verbose("bus_check_queued_message_reply_callback called message=%p\n", deferred_message);
 
-  if (!bus_connection_is_active(deferred_message->proposed_recipient))
+  if (!(dbus_connection_get_is_connected(deferred_message->proposed_recipient)
+                         && bus_connection_is_active(deferred_message->proposed_recipient)))
     return;
 
   status = deferred_message->status;
@@ -495,7 +496,7 @@ bus_deferred_message_dispatch (BusDeferredMessage *deferred_message)
     }
 
   /* do not attempt to send message if sender has disconnected */
-  if (deferred_message->sender != NULL && !bus_connection_is_active(deferred_message->sender))
+  if (deferred_message->sender != NULL && !(dbus_connection_get_is_connected(deferred_message->sender) && bus_connection_is_active(deferred_message->sender)))
     {
       bus_transaction_cancel_and_free(transaction);
       result = BUS_RESULT_FALSE;