critical error in bonobo_object_unref(): assertion `ao != NULL' failed

Ben Liblit <[email protected]> Mon, 25 Aug 2003 23:34:24 -0700
Newsgroups gmane.comp.gnome.components
Message-ID <[email protected]>
I need some help tracking down the cause of the following error message, 
which appears just before my Bonobo server terminates:

     Bonobo-CRITICAL **: file bonobo-object.c: line 286
     (bonobo_object_unref): assertion `ao != NULL' failed

Let me back up and describe the different pieces.  I am trying to create 
a Bonobo-based server that does not use BonoboGenericFactory.  Rather, 
the server is a singleton: its executable creates a single instance 
which it registers with Bonobo activation directly.  I have been unable 
to find even a single Bonobo code example that doesn't use factories, 
which may be why I'm getting into trouble.

The server singleton is an instance of a subclass of BonoboObject.  I 
call bonobo_activation_register_active_server() on the embedded CORBA 
object to register its existence.  I pass the server instnce itself in a 
call to bonobo_running_context_auto_exit_unref().  Then I drop into 
bonobo_main() and begin serving client requests.

The client calls bonobo_get_object() to get a handle on the server and 
then performs a few trivial method calls that just print out diagnostic 
messages.  The client finishes by calling bonobo_object_release_unref() 
on the same server handle originally returned by bonobo_get_object().

To simplify debugging, I manually launch the server first and then a 
single client.  When the client completes the last of its requests and 
calls bonobo_object_release_unref(), the diagnostic message I described 
earlier is printed by the server process:

     Bonobo-CRITICAL **: file bonobo-object.c: line 286
     (bonobo_object_unref): assertion `ao != NULL' failed

Presumably I am mis-managing reference counts somewhere, but I don't see 
how.  Other than the client's call to bonobo_object_unref(), I am never 
explicitly ref'ing or unref'ing anything.  The server's main() is 
basically just:

	bonobo_init(&argc, argv);

	Server *server = g_object_new(...);
	CORBA_Object obj = BONOBO_OBJREF(server);
	bonobo_activation_register_active_server(..., obj, ...);

	bonobo_running_context_auto_exit_unref(BONOBO_OBJECT(server));
	bonobo_main();
   	return bonobo_debug_shutdown();

(I've omitted error checking to make this code snippet smaller, but I am 
checking all calls for errors.)

 From stepping around in GDB I can say that server->parent.priv->ao is 
non-NULL when I initially call bonobo_main().  It is assigned NULL 
during a call to bonobo_object_finalize_internal():

	#0  bonobo_object_finalize_internal (ao=0x805b448)
	    at bonobo-object.c:171
	#1  bonobo_object_unref (obj=0x805b448) at bonobo-object.c:297
	#2  impl_Bonobo_Unknown_unref (servant=0x805b46c,
	    ev=0xbffff5a0) at bonobo-object.c:553
	#3  _ORBIT_skel_small_Bonobo_Unknown_unref ()
	#4  ORBit_POA_setup_root ()
	#5  ORBit_OAObject_invoke ()
	#6  ORBit_small_invoke_adaptor ()
	#7  ORBit_recv_buffer_return_sys_exception ()
	#8  ORBit_recv_buffer_return_sys_exception ()
	#9  ORBit_handle_request ()
	#10 giop_connection_handle_input ()
	#11 linc_connection_set_max_buffer ()
	#12 linc_server_get_type ()
	#13 unblock_source ()
	#14 g_main_context_dispatch ()
	#15 g_main_context_dispatch ()
	#16 g_main_loop_run ()
	#17 bonobo_main () at bonobo-main.c:293
	#18 main (argc=1, argv=0xbffff834) at server-main.c:38
	#19 __libc_start_main ()

The error-printing call to bonobo_object_unref() comes soon thereafter:

	#0  bonobo_object_unref (obj=0x0) at bonobo-object.c:286
	#1  last_unref_exit_cb (context=0x8052488, object=0x805b458)
            at bonobo-running-context.c:399
	#2  g_cclosure_marshal_VOID__VOID ()
	#3  g_closure_invoke ()
	#4  g_signal_emit_by_name ()
	#5  g_signal_emit_valist ()
	#6  g_signal_emit ()
	#7  check_empty () at bonobo-running-context.c:134
	#8  bonobo_object_corba_deactivate (object=0x805b458)
             at bonobo-object.c:112
	#9  bonobo_object_finalize_internal (ao=0x805b448)
	    at bonobo-object.c:173

	... remainder of stack is the same as previous ...

(Don't be fooled by the obj=0x0 in the call to bonobo_object_unref(). 
This is a side effect of compiler optimization; the actual parameter 
value is 0x805b458.  If it were really NULL, we wouldn't even have 
gotten to the failed "ao != NULL" assertion on line 286.)

Can anyone see what I might be doing wrong?

Thank you.