After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 463730 - Hang on startup
Hang on startup
Status: RESOLVED DUPLICATE of bug 446565
Product: glib
Classification: Platform
Component: gobject
unspecified
Other Linux
: Normal major
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2007-08-05 19:09 UTC by Ed Catmur
Modified: 2007-08-13 23:27 UTC
See Also:
GNOME target: ---
GNOME version: 2.19/2.20


Attachments
g_type_init_O3_fix.patch (288 bytes, patch)
2007-08-05 21:44 UTC, Ed Catmur
none Details | Review
totem-declare-noreturn.patch (426 bytes, patch)
2007-08-06 22:33 UTC, Ed Catmur
committed Details | Review

Description Ed Catmur 2007-08-05 19:09:18 UTC
totem-2.19.6 hangs on startup, with a lot of critical errors to console:

$ totem
(process:16379): GLib-GObject-CRITICAL **: gtype.c:2242: initialization assertion failed, use IA__g_type_init() prior to this function

(process:16379): GLib-CRITICAL **: g_once_init_leave: assertion `initialization_value != 0' failed

(process:16379): GLib-GObject-CRITICAL **: gtype.c:2242: initialization assertion failed, use IA__g_type_init() prior to this function

(process:16379): GLib-GObject-CRITICAL **: gtype.c:2242: initialization assertion failed, use IA__g_type_init() prior to this function

(process:16379): GLib-GObject-CRITICAL **: gtype.c:2242: initialization assertion failed, use IA__g_type_init() prior to this function

(process:16379): GLib-GObject-CRITICAL **: g_type_add_interface_static: assertion `G_TYPE_IS_INSTANTIATABLE (instance_type)' failed

(process:16379): GLib-GObject-CRITICAL **: gtype.c:2242: initialization assertion failed, use IA__g_type_init() prior to this function

(process:16379): GLib-GObject-CRITICAL **: g_type_add_interface_static: assertion `G_TYPE_IS_INSTANTIATABLE (instance_type)' failed

(process:16379): GLib-GObject-CRITICAL **: gtype.c:2242: initialization assertion failed, use IA__g_type_init() prior to this function

(process:16379): GLib-GObject-CRITICAL **: gtype.c:2242: initialization assertion failed, use IA__g_type_init() prior to this function

(process:16379): GLib-GObject-CRITICAL **: g_type_add_interface_static: assertion `G_TYPE_IS_INSTANTIATABLE (instance_type)' failed

(process:16379): GLib-GObject-CRITICAL **: gtype.c:2242: initialization assertion failed, use IA__g_type_init() prior to this function

(process:16379): GLib-CRITICAL **: g_once_init_leave: assertion `initialization_value != 0' failed

(process:16379): GLib-GObject-CRITICAL **: gtype.c:2242: initialization assertion failed, use IA__g_type_init() prior to this function

(process:16379): GLib-GObject-CRITICAL **: gtype.c:2242: initialization assertion failed, use IA__g_type_init() prior to this function

(process:16379): GLib-GObject-CRITICAL **: g_type_add_interface_static: assertion `G_TYPE_IS_INSTANTIATABLE (instance_type)' failed

(process:16379): GLib-CRITICAL **: g_once_init_leave: assertion `initialization_value != 0' failed
Comment 1 Ed Catmur 2007-08-05 19:09:49 UTC
strace shows it hanging inside futex:

...
open("/usr/share/locale/locale.alias", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=2586, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f04000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2586
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0xb7f04000, 4096)                = 0
geteuid32()                             = 500
getuid32()                              = 500
getegid32()                             = 100
getgid32()                              = 100
futex(0x809dfcc, FUTEX_WAIT, 1, NULL
Comment 2 Ed Catmur 2007-08-05 19:12:10 UTC
gdb is useless:
Program received signal SIGINT, Interrupt.

Thread NaN (LWP 16428)

  • #0 IA__g_logv
  • #1 IA__g_log
  • #2 IA__g_type_register_static
    at gtype.c line 2242
  • #3 IA__g_type_register_static_simple
    at gtype.c line 2230
  • #4 IA__g_initially_unowned_get_type
    at gobject.c line 2253
  • #5 IA__gtk_object_get_type
    at gtkobject.c line 99
  • #6 IA__gtk_widget_get_type
    at gtkwidget.c line 346
  • #7 IA__gtk_container_get_type
    at gtkcontainer.c line 164
  • #8 IA__gtk_bin_get_type
    at gtkbin.c line 43
  • #9 IA__gtk_window_get_type
    at gtkwindow.c line 335
  • #10 main
    at totem.c line 3023

This is odd; line 3023 of totem.c is the opening { of main().
Comment 3 Ed Catmur 2007-08-05 19:12:49 UTC
Ah... totem was compiled with -O3 -fno-strict-aliasing (on Gentoo); could this be an optimisation bug?
Comment 4 Ed Catmur 2007-08-05 19:46:57 UTC
Yes; here's the disassembly of main():

Dump of assembler code for function main:
0x08062100 <main+0>:	lea    0x4(%esp),%ecx
0x08062104 <main+4>:	and    $0xfffffff0,%esp
0x08062107 <main+7>:	pushl  0xfffffffc(%ecx)
0x0806210a <main+10>:	push   %ebp
0x0806210b <main+11>:	mov    %esp,%ebp
0x0806210d <main+13>:	push   %edi
0x0806210e <main+14>:	push   %esi
0x0806210f <main+15>:	push   %ebx
0x08062110 <main+16>:	push   %ecx
0x08062111 <main+17>:	sub    $0x68,%esp
0x08062114 <main+20>:	mov    %ecx,0xffffffb4(%ebp)
0x08062117 <main+23>:	movl   $0x808f234,0x4(%esp)
0x0806211f <main+31>:	movl   $0x8090255,(%esp)
0x08062126 <main+38>:	call   0x805acac <bindtextdomain@plt>
0x0806212b <main+43>:	movl   $0x808f246,0x4(%esp)
0x08062133 <main+51>:	movl   $0x8090255,(%esp)
0x0806213a <main+58>:	call   0x805c41c <bind_textdomain_codeset@plt>
0x0806213f <main+63>:	movl   $0x8090255,(%esp)
0x08062146 <main+70>:	call   0x805b93c <textdomain@plt>
0x0806214b <main+75>:	call   0x8059cdc <XInitThreads@plt>
0x08062150 <main+80>:	test   %eax,%eax
0x08062152 <main+82>:	je     0x8062ba3 <main+2723>
0x08062158 <main+88>:	call   0x805a85c <gtk_window_get_type@plt>
0x0806215d <main+93>:	mov    %eax,0xffffffd4(%ebp)
0x08062160 <main+96>:	movl   $0x0,(%esp)
0x08062167 <main+103>:	call   0x805b02c <g_thread_init@plt>
0x0806216c <main+108>:	movl   $0x808f24c,(%esp)
0x08062173 <main+115>:	call   0x805c22c <g_option_context_new@plt>
0x08062178 <main+120>:	mov    %eax,%ebx
0x0806217a <main+122>:	call   0x8075d80 <bacon_video_widget_get_option_group>
0x0806217f <main+127>:	movl   $0x8090255,0x8(%esp)
0x08062187 <main+135>:	movl   $0x8090760,0x4(%esp)
0x0806218f <main+143>:	mov    %eax,%esi
0x08062191 <main+145>:	mov    %ebx,(%esp)
0x08062194 <main+148>:	call   0x805c8cc <g_option_context_add_main_entries@plt>
0x08062199 <main+153>:	movl   $0x8090255,0x4(%esp)
0x080621a1 <main+161>:	mov    %ebx,(%esp)
0x080621a4 <main+164>:	call   0x805a71c <g_option_context_set_translation_domain@plt>

For reference here's the corresponding source:

int
main (int argc, char **argv)
{
	Totem *totem;
	GConfClient *gc;
#ifndef HAVE_GTK_ONLY
	GnomeProgram *program;
#else
	GError *error = NULL;
#endif
	GOptionContext *context;
	GOptionGroup *baconoptiongroup;

	bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

#ifdef GDK_WINDOWING_X11
	if (XInitThreads () == 0)
	{
		gtk_init (&argc, &argv);
		g_set_application_name (_("Totem Movie Player"));
		totem_action_error_and_exit (_("Could not initialize the thread-safe libraries."), _("Verify your system installation. Totem will now exit."), NULL);
	}
#endif

	g_thread_init (NULL);

	/* Handle command line arguments */
	context = g_option_context_new (N_("- Play movies and songs"));
	baconoptiongroup = bacon_video_widget_get_option_group();
	g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
	g_option_context_set_translation_domain(context, GETTEXT_PACKAGE);

gtk_window_get_type() doesn't get used until way later in main(), at line 3118:

	totem->fs = totem_fullscreen_new (GTK_WINDOW (totem->win));

Why is gcc moving it up inside the function?
Comment 5 Ed Catmur 2007-08-05 21:22:22 UTC
OK, using a j to skip that call to gtk_window_get_type() prevents the hang (and the critical warnings), so that's the issue; still need to find out why gcc thinks it can reorder it.
Comment 6 Ed Catmur 2007-08-05 21:25:56 UTC
Ah - gtk_window_get_type() is marked as G_GNUC_CONST.  But it's not deserving of const attribute, because it is dependent on and affects the GType system (g_type_init()).  Would G_GNUC_PURE work better?
Comment 7 Ed Catmur 2007-08-05 21:42:42 UTC
Yes, it does; but waiting on GTK+ to fix gtkwindow.h isn't going to fix totem.  Perhaps an early g_type_init()?
Comment 8 Ed Catmur 2007-08-05 21:44:53 UTC
Created attachment 93120 [details] [review]
g_type_init_O3_fix.patch

Yes, this works.  Bit of a nasty hack though.
Comment 9 Bastien Nocera 2007-08-05 22:03:43 UTC
That clearly is either a GCC, or a GTK+/glib bug. GTK+ is supposed to initialise the type system just before parsing the options.

Punting to glib. Are we supposed to init the type system beforehand, even if we use gtk_get_option_group().
Comment 10 Ed Catmur 2007-08-05 22:11:55 UTC
Type system initialisation is supposed to, and does, occur in g_option_context_parse() or gnome_program_init() (depending on whether Totem is compiled with Gnome libs).

The issue is that gcc is moving a gtk_window_get_type() call to before the type system is initialised.  The problem is that GTK+ headers are abusing __attribute__((const)).  I've submitted bug 463781; see also bug 446565.
Comment 11 Matthias Clasen 2007-08-05 23:26:53 UTC
Be that as it may, gcc -O3 is perhaps a bit too aggressive in breaking code that has been working for a long time.
Comment 12 Ed Catmur 2007-08-06 21:28:28 UTC
-O2 -finline-functions
-O -ftree-pre -finline-functions

(-ftree-pre is Partial Redundancy Elimination, enabled at -O2.)

Both of these (under gcc 4.2.0) will cause the above broken asm to be emitted.

Is -finline-functions really such an aggressive optimisation?
Comment 13 Ed Catmur 2007-08-06 22:26:32 UTC
Here's a minimal reduced testcase of totem.c:

#include <glib-object.h>
#include <stdlib.h>

int main (int argc, char **argv) {
	if (argc == 0) {
		g_type_init ();
		volatile GType t = g_type_module_get_type();
		g_error ("oops");
	}

	g_type_init ();
	volatile GType t = g_type_module_get_type();
	return 0;
}

n.b. g_type_module_get_type() is declared with G_GNUC_CONST.
Comment 14 Ed Catmur 2007-08-06 22:29:06 UTC
Note the above breaks with "gcc -O2" and with "gcc -O -ftree-pre"; no -finline-functions or -O3 needed.
Comment 15 Ed Catmur 2007-08-06 22:30:57 UTC
M'kay... that's interesting.  The bug disappears if totem_action_exit() (called from within totem_action_error_and_exit()) is declared G_GNUC_NORETURN.  A more elegant workaround perhaps.
Comment 16 Ed Catmur 2007-08-06 22:33:32 UTC
Created attachment 93175 [details] [review]
totem-declare-noreturn.patch
Comment 17 Bastien Nocera 2007-08-12 13:03:16 UTC
2007-08-12  Bastien Nocera  <hadess@hadess.net>

        * src/plparse/totem-pl-parser.c:
        (totem_pl_parser_can_parse_from_data):
        Add more debug when a mime-type isn't known
 
        * src/totem.h: Add patch from Ed Catmur <ed@catmur.co.uk>
        to avoid hangs with specific versions of GCC and a set of
        optimisations (Closes: #463730)

The bug still lies with GCC, IMO.
Comment 18 Tim Janik 2007-08-13 23:27:30 UTC

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