Subject: Re: bug#1186: 23.0.60; Abort trap when loading dbus in tty

From: Michael Albinus <[email-masked]>
Date: Thu, 23 Oct 2008 15:29:09 +0200

Magnus Henoch <[email-masked]> writes:

> With more debugging and less optimization I get:
>
> xd_read_message: Event received: DBUS_MESSAGE_TYPE_SIGNAL 2 org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus NameAcquired (:1.10)
> Breakpoint 1, abort () at /media/e/src/emacs/src/emacs.c:424              xd_retrieve_arg: s :1.10
> 424       kill (getpid (), SIGABRT);
> (gdb) bt full
> #0  abort () at /media/e/src/emacs/src/emacs.c:424
> No locals.
> #1  0x01a566cc in Fsignal (error_symbol=30504705, data=45395581) at /media/e/src/emacs/src/eval.c:1651
>         allhandlers = (struct handler *) 0xffffc408
>         conditions = -277077180
>         string = -277132056
>         real_error_symbol = 190
>         bp = (struct backtrace *) 0x25d9273
> #2  0x01a56ab4 in xsignal (error_symbol=30504705, data=45395581) at /media/e/src/emacs/src/eval.c:1750
> No locals.
> #3  0x01a56b18 in xsignal1 (error_symbol=30504705, arg=39686771) at /media/e/src/emacs/src/eval.c:1767
> No locals.
> #4  0x01986158 in xd_initialize (bus=30504729) at /media/e/src/emacs/src/dbusbind.c:688
>         s = "Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection w"...
>         connection = (DBusConnection *) 0x0
>         derror = {
>   name = 0x0, 
>   message = 0x0, 
>   dummy1 = 1, 
>   dummy2 = 0, 
>   dummy3 = 0, 
>   dummy4 = 0, 
>   dummy5 = 0, 
>   padding1 = 0xffffb850
> }

Thank you for the backtrace, it makes the picture clear. Fsignal must
not be called when reading events in the main loop. But xd_initialize does.

Could you, please, check the appended patch? It ought to prevent Fsignal
calls in this case.

> Magnus

Best regards, Michael.

*** /home/albinus/src/emacs/src/dbusbind.c.~1~	Sun Oct 19 20:09:34 2008
--- /home/albinus/src/emacs/src/dbusbind.c	Thu Oct 23 14:47:40 2008
***************
*** 63,72 ****
--- 63,101 ----
  /* Whether to debug D-Bus.  */
  Lisp_Object Vdbus_debug;
  
+ /* Whether we are reading a D-Bus event.  */
+ int xd_in_read_queued_messages = 0;
+ 
  
  /* We use "xd_" and "XD_" as prefix for all internal symbols, because
     we don't want to poison other namespaces with "dbus_".  */
  
+ /* Raise a signal.  If we are reading events, we cannot signal; we
+    throw to xd_read_queued_messages then.  */
+ #define XD_SIGNAL1(arg)							\
+   do {									\
+     if (xd_in_read_queued_messages)					\
+       Fthrow (Qdbus_error, Qnil);					\
+     else								\
+       xsignal1 (Qdbus_error, arg);					\
+   } while (0)
+ 
+ #define XD_SIGNAL2(arg1, arg2)						\
+   do {									\
+     if (xd_in_read_queued_messages)					\
+       Fthrow (Qdbus_error, Qnil);					\
+     else								\
+       xsignal2 (Qdbus_error, arg1, arg2);				\
+   } while (0)
+ 
+ #define XD_SIGNAL3(arg1, arg2, arg3)					\
+   do {									\
+     if (xd_in_read_queued_messages)					\
+       Fthrow (Qdbus_error, Qnil);					\
+     else								\
+       xsignal3 (Qdbus_error, arg1, arg2, arg3);				\
+   } while (0)
+ 
  /* Raise a Lisp error from a D-Bus ERROR.  */
  #define XD_ERROR(error)							\
    do {									\
***************
*** 76,82 ****
      /* Remove the trailing newline.  */					\
      if (strchr (s, '\n') != NULL)					\
        s[strlen (s) - 1] = '\0';						\
!     xsignal1 (Qdbus_error, build_string (s));				\
    } while (0)
  
  /* Macros for debugging.  In order to enable them, build with
--- 105,111 ----
      /* Remove the trailing newline.  */					\
      if (strchr (s, '\n') != NULL)					\
        s[strlen (s) - 1] = '\0';						\
!     XD_SIGNAL1 (build_string (s));					\
    } while (0)
  
  /* Macros for debugging.  In order to enable them, build with
***************
*** 94,100 ****
      if (!valid_lisp_object_p (object))					\
        {									\
  	XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__);		\
! 	xsignal1 (Qdbus_error, build_string ("Assertion failure"));	\
        }									\
    } while (0)
  
--- 123,129 ----
      if (!valid_lisp_object_p (object))					\
        {									\
  	XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__);		\
! 	XD_SIGNAL1 (build_string ("Assertion failure"));		\
        }									\
    } while (0)
  
***************
*** 370,377 ****
  	  unsigned char val = XUINT (object) & 0xFF;
  	  XD_DEBUG_MESSAGE ("%c %d", dtype, val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    xsignal2 (Qdbus_error,
! 		      build_string ("Unable to append argument"), object);
  	  return;
  	}
  
--- 399,405 ----
  	  unsigned char val = XUINT (object) & 0xFF;
  	  XD_DEBUG_MESSAGE ("%c %d", dtype, val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    XD_SIGNAL2 (build_string ("Unable to append argument"), object);
  	  return;
  	}
  
***************
*** 380,387 ****
  	  dbus_bool_t val = (NILP (object)) ? FALSE : TRUE;
  	  XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    xsignal2 (Qdbus_error,
! 		      build_string ("Unable to append argument"), object);
  	  return;
  	}
  
--- 408,414 ----
  	  dbus_bool_t val = (NILP (object)) ? FALSE : TRUE;
  	  XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    XD_SIGNAL2 (build_string ("Unable to append argument"), object);
  	  return;
  	}
  
***************
*** 390,397 ****
  	  dbus_int16_t val = XINT (object);
  	  XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    xsignal2 (Qdbus_error,
! 		      build_string ("Unable to append argument"), object);
  	  return;
  	}
  
--- 417,423 ----
  	  dbus_int16_t val = XINT (object);
  	  XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    XD_SIGNAL2 (build_string ("Unable to append argument"), object);
  	  return;
  	}
  
***************
*** 400,407 ****
  	  dbus_uint16_t val = XUINT (object);
  	  XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    xsignal2 (Qdbus_error,
! 		      build_string ("Unable to append argument"), object);
  	  return;
  	}
  
--- 426,432 ----
  	  dbus_uint16_t val = XUINT (object);
  	  XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    XD_SIGNAL2 (build_string ("Unable to append argument"), object);
  	  return;
  	}
  
***************
*** 410,417 ****
  	  dbus_int32_t val = XINT (object);
  	  XD_DEBUG_MESSAGE ("%c %d", dtype, val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    xsignal2 (Qdbus_error,
! 		      build_string ("Unable to append argument"), object);
  	  return;
  	}
  
--- 435,441 ----
  	  dbus_int32_t val = XINT (object);
  	  XD_DEBUG_MESSAGE ("%c %d", dtype, val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    XD_SIGNAL2 (build_string ("Unable to append argument"), object);
  	  return;
  	}
  
***************
*** 420,427 ****
  	  dbus_uint32_t val = XUINT (object);
  	  XD_DEBUG_MESSAGE ("%c %u", dtype, val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    xsignal2 (Qdbus_error,
! 		      build_string ("Unable to append argument"), object);
  	  return;
  	}
  
--- 444,450 ----
  	  dbus_uint32_t val = XUINT (object);
  	  XD_DEBUG_MESSAGE ("%c %u", dtype, val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    XD_SIGNAL2 (build_string ("Unable to append argument"), object);
  	  return;
  	}
  
***************
*** 430,437 ****
  	  dbus_int64_t val = XINT (object);
  	  XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    xsignal2 (Qdbus_error,
! 		      build_string ("Unable to append argument"), object);
  	  return;
  	}
  
--- 453,459 ----
  	  dbus_int64_t val = XINT (object);
  	  XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    XD_SIGNAL2 (build_string ("Unable to append argument"), object);
  	  return;
  	}
  
***************
*** 440,447 ****
  	  dbus_uint64_t val = XUINT (object);
  	  XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    xsignal2 (Qdbus_error,
! 		      build_string ("Unable to append argument"), object);
  	  return;
  	}
  
--- 462,468 ----
  	  dbus_uint64_t val = XUINT (object);
  	  XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    XD_SIGNAL2 (build_string ("Unable to append argument"), object);
  	  return;
  	}
  
***************
*** 449,456 ****
  	XD_DEBUG_MESSAGE ("%c %f", dtype, XFLOAT_DATA (object));
  	if (!dbus_message_iter_append_basic (iter, dtype,
  					     &XFLOAT_DATA (object)))
! 	  xsignal2 (Qdbus_error,
! 		    build_string ("Unable to append argument"), object);
  	return;
  
        case DBUS_TYPE_STRING:
--- 470,476 ----
  	XD_DEBUG_MESSAGE ("%c %f", dtype, XFLOAT_DATA (object));
  	if (!dbus_message_iter_append_basic (iter, dtype,
  					     &XFLOAT_DATA (object)))
! 	  XD_SIGNAL2 (build_string ("Unable to append argument"), object);
  	return;
  
        case DBUS_TYPE_STRING:
***************
*** 460,467 ****
  	  char *val = SDATA (Fstring_make_unibyte (object));
  	  XD_DEBUG_MESSAGE ("%c %s", dtype, val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    xsignal2 (Qdbus_error,
! 		      build_string ("Unable to append argument"), object);
  	  return;
  	}
        }
--- 480,486 ----
  	  char *val = SDATA (Fstring_make_unibyte (object));
  	  XD_DEBUG_MESSAGE ("%c %s", dtype, val);
  	  if (!dbus_message_iter_append_basic (iter, dtype, &val))
! 	    XD_SIGNAL2 (build_string ("Unable to append argument"), object);
  	  return;
  	}
        }
***************
*** 509,517 ****
  			    SDATA (format2 ("%s", object, Qnil)));
  	  if (!dbus_message_iter_open_container (iter, dtype,
  						 signature, &subiter))
! 	    xsignal3 (Qdbus_error,
! 		      build_string ("Cannot open container"),
! 		      make_number (dtype), build_string (signature));
  	  break;
  
  	case DBUS_TYPE_VARIANT:
--- 528,535 ----
  			    SDATA (format2 ("%s", object, Qnil)));
  	  if (!dbus_message_iter_open_container (iter, dtype,
  						 signature, &subiter))
! 	    XD_SIGNAL3 (build_string ("Cannot open container"),
! 			make_number (dtype), build_string (signature));
  	  break;
  
  	case DBUS_TYPE_VARIANT:
***************
*** 523,531 ****
  			    SDATA (format2 ("%s", object, Qnil)));
  	  if (!dbus_message_iter_open_container (iter, dtype,
  						 signature, &subiter))
! 	    xsignal3 (Qdbus_error,
! 		      build_string ("Cannot open container"),
! 		      make_number (dtype), build_string (signature));
  	  break;
  
  	case DBUS_TYPE_STRUCT:
--- 541,548 ----
  			    SDATA (format2 ("%s", object, Qnil)));
  	  if (!dbus_message_iter_open_container (iter, dtype,
  						 signature, &subiter))
! 	    XD_SIGNAL3 (build_string ("Cannot open container"),
! 			make_number (dtype), build_string (signature));
  	  break;
  
  	case DBUS_TYPE_STRUCT:
***************
*** 534,542 ****
  	  XD_DEBUG_MESSAGE ("%c %s", dtype,
  			    SDATA (format2 ("%s", object, Qnil)));
  	  if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter))
! 	    xsignal2 (Qdbus_error,
! 		      build_string ("Cannot open container"),
! 		      make_number (dtype));
  	  break;
  	}
  
--- 551,558 ----
  	  XD_DEBUG_MESSAGE ("%c %s", dtype,
  			    SDATA (format2 ("%s", object, Qnil)));
  	  if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter))
! 	    XD_SIGNAL2 (build_string ("Cannot open container"),
! 			make_number (dtype));
  	  break;
  	}
  
***************
*** 553,561 ****
  
        /* Close the subiteration.  */
        if (!dbus_message_iter_close_container (iter, &subiter))
! 	xsignal2 (Qdbus_error,
! 		  build_string ("Cannot close container"),
! 		  make_number (dtype));
      }
  }
  
--- 569,576 ----
  
        /* Close the subiteration.  */
        if (!dbus_message_iter_close_container (iter, &subiter))
! 	XD_SIGNAL2 (build_string ("Cannot close container"),
! 		    make_number (dtype));
      }
  }
  
***************
*** 677,683 ****
    /* Parameter check.  */
    CHECK_SYMBOL (bus);
    if (!((EQ (bus, QCdbus_system_bus)) || (EQ (bus, QCdbus_session_bus))))
!     xsignal2 (Qdbus_error, build_string ("Wrong bus name"), bus);
  
    /* Open a connection to the bus.  */
    dbus_error_init (&derror);
--- 692,698 ----
    /* Parameter check.  */
    CHECK_SYMBOL (bus);
    if (!((EQ (bus, QCdbus_system_bus)) || (EQ (bus, QCdbus_session_bus))))
!     XD_SIGNAL2 (build_string ("Wrong bus name"), bus);
  
    /* Open a connection to the bus.  */
    dbus_error_init (&derror);
***************
*** 691,697 ****
      XD_ERROR (derror);
  
    if (connection == NULL)
!     xsignal2 (Qdbus_error, build_string ("No connection"), bus);
  
    /* Return the result.  */
    return connection;
--- 706,712 ----
      XD_ERROR (derror);
  
    if (connection == NULL)
!     XD_SIGNAL2 (build_string ("No connection"), bus);
  
    /* Return the result.  */
    return connection;
***************
*** 715,721 ****
    /* Request the name.  */
    name = dbus_bus_get_unique_name (connection);
    if (name == NULL)
!     xsignal1 (Qdbus_error, build_string ("No unique name available"));
  
    /* Return.  */
    return build_string (name);
--- 730,736 ----
    /* Request the name.  */
    name = dbus_bus_get_unique_name (connection);
    if (name == NULL)
!     XD_SIGNAL1 (build_string ("No unique name available"));
  
    /* Return.  */
    return build_string (name);
***************
*** 836,842 ****
  					   SDATA (method));
    UNGCPRO;
    if (dmessage == NULL)
!     xsignal1 (Qdbus_error, build_string ("Unable to create a new message"));
  
    /* Check for timeout parameter.  */
    if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
--- 851,857 ----
  					   SDATA (method));
    UNGCPRO;
    if (dmessage == NULL)
!     XD_SIGNAL1 (build_string ("Unable to create a new message"));
  
    /* Check for timeout parameter.  */
    if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
***************
*** 887,893 ****
      XD_ERROR (derror);
  
    if (reply == NULL)
!     xsignal1 (Qdbus_error, build_string ("No reply"));
  
    XD_DEBUG_MESSAGE ("Message sent");
  
--- 902,908 ----
      XD_ERROR (derror);
  
    if (reply == NULL)
!     XD_SIGNAL1 (build_string ("No reply"));
  
    XD_DEBUG_MESSAGE ("Message sent");
  
***************
*** 1018,1024 ****
  					   SDATA (interface),
  					   SDATA (method));
    if (dmessage == NULL)
!     xsignal1 (Qdbus_error, build_string ("Unable to create a new message"));
  
    /* Check for timeout parameter.  */
    if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
--- 1033,1039 ----
  					   SDATA (interface),
  					   SDATA (method));
    if (dmessage == NULL)
!     XD_SIGNAL1 (build_string ("Unable to create a new message"));
  
    /* Check for timeout parameter.  */
    if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
***************
*** 1061,1067 ****
    /* Send the message.  The message is just added to the outgoing
       message queue.  */
    if (!dbus_connection_send_with_reply (connection, dmessage, NULL, timeout))
!     xsignal1 (Qdbus_error, build_string ("Cannot send message"));
  
    XD_DEBUG_MESSAGE ("Message sent");
  
--- 1076,1082 ----
    /* Send the message.  The message is just added to the outgoing
       message queue.  */
    if (!dbus_connection_send_with_reply (connection, dmessage, NULL, timeout))
!     XD_SIGNAL1 (build_string ("Cannot send message"));
  
    XD_DEBUG_MESSAGE ("Message sent");
  
***************
*** 1120,1127 ****
        || (!dbus_message_set_destination (dmessage, SDATA (service))))
      {
        UNGCPRO;
!       xsignal1 (Qdbus_error,
! 		build_string ("Unable to create a return message"));
      }
  
    UNGCPRO;
--- 1135,1141 ----
        || (!dbus_message_set_destination (dmessage, SDATA (service))))
      {
        UNGCPRO;
!       XD_SIGNAL1 (build_string ("Unable to create a return message"));
      }
  
    UNGCPRO;
***************
*** 1159,1165 ****
    /* Send the message.  The message is just added to the outgoing
       message queue.  */
    if (!dbus_connection_send (connection, dmessage, NULL))
!     xsignal1 (Qdbus_error, build_string ("Cannot send message"));
  
    /* Flush connection to ensure the message is handled.  */
    dbus_connection_flush (connection);
--- 1173,1179 ----
    /* Send the message.  The message is just added to the outgoing
       message queue.  */
    if (!dbus_connection_send (connection, dmessage, NULL))
!     XD_SIGNAL1 (build_string ("Cannot send message"));
  
    /* Flush connection to ensure the message is handled.  */
    dbus_connection_flush (connection);
***************
*** 1216,1223 ****
        || (!dbus_message_set_destination (dmessage, SDATA (service))))
      {
        UNGCPRO;
!       xsignal1 (Qdbus_error,
! 		build_string ("Unable to create a error message"));
      }
  
    UNGCPRO;
--- 1230,1236 ----
        || (!dbus_message_set_destination (dmessage, SDATA (service))))
      {
        UNGCPRO;
!       XD_SIGNAL1 (build_string ("Unable to create a error message"));
      }
  
    UNGCPRO;
***************
*** 1255,1261 ****
    /* Send the message.  The message is just added to the outgoing
       message queue.  */
    if (!dbus_connection_send (connection, dmessage, NULL))
!     xsignal1 (Qdbus_error, build_string ("Cannot send message"));
  
    /* Flush connection to ensure the message is handled.  */
    dbus_connection_flush (connection);
--- 1268,1274 ----
    /* Send the message.  The message is just added to the outgoing
       message queue.  */
    if (!dbus_connection_send (connection, dmessage, NULL))
!     XD_SIGNAL1 (build_string ("Cannot send message"));
  
    /* Flush connection to ensure the message is handled.  */
    dbus_connection_flush (connection);
***************
*** 1340,1346 ****
  				      SDATA (signal));
    UNGCPRO;
    if (dmessage == NULL)
!     xsignal1 (Qdbus_error, build_string ("Unable to create a new message"));
  
    /* Initialize parameter list of message.  */
    dbus_message_iter_init_append (dmessage, &iter);
--- 1353,1359 ----
  				      SDATA (signal));
    UNGCPRO;
    if (dmessage == NULL)
!     XD_SIGNAL1 (build_string ("Unable to create a new message"));
  
    /* Initialize parameter list of message.  */
    dbus_message_iter_init_append (dmessage, &iter);
***************
*** 1375,1381 ****
    /* Send the message.  The message is just added to the outgoing
       message queue.  */
    if (!dbus_connection_send (connection, dmessage, NULL))
!     xsignal1 (Qdbus_error, build_string ("Cannot send message"));
  
    /* Flush connection to ensure the message is handled.  */
    dbus_connection_flush (connection);
--- 1388,1394 ----
    /* Send the message.  The message is just added to the outgoing
       message queue.  */
    if (!dbus_connection_send (connection, dmessage, NULL))
!     XD_SIGNAL1 (build_string ("Cannot send message"));
  
    /* Flush connection to ensure the message is handled.  */
    dbus_connection_flush (connection);
***************
*** 1557,1566 ****
       Lisp errors during the call.  */
    if (HASH_TABLE_P (Vdbus_registered_functions_table))
      {
!       internal_condition_case_1 (xd_read_message, QCdbus_system_bus,
! 				 Qerror, Fidentity);
!       internal_condition_case_1 (xd_read_message, QCdbus_session_bus,
! 				 Qerror, Fidentity);
      }
  }
  
--- 1570,1579 ----
       Lisp errors during the call.  */
    if (HASH_TABLE_P (Vdbus_registered_functions_table))
      {
!       xd_in_read_queued_messages = 1;
!       internal_catch (Qdbus_error, xd_read_message, QCdbus_system_bus);
!       internal_catch (Qdbus_error, xd_read_message, QCdbus_session_bus);
!       xd_in_read_queued_messages = 0;
      }
  }