Ошибка сегментации при включении оптимизации в простом приложении GTK +? - PullRequest
5 голосов
/ 30 января 2011

Возможно, уже слишком поздно, но я нахожу по меньшей мере любопытным, что следующие несколько строк вызывают ошибку сегментации тогда и только тогда, когда она компилируется с оптимизацией gcc, даже "-O1"!

settings_dialog = gtk_dialog_new_with_buttons("gatotray Settings"
    , NULL, 0, GTK_STOCK_CANCEL, FALSE, GTK_STOCK_SAVE, TRUE, 0);
g_signal_connect(G_OBJECT(settings_dialog), "response", G_CALLBACK(gtk_widget_destroy), NULL);
g_signal_connect(G_OBJECT(settings_dialog), "destroy", G_CALLBACK(settings_destroyed), NULL);
GtkWidget *vb = gtk_dialog_get_content_area(GTK_DIALOG(settings_dialog));
GtkWidget *hb = gtk_hbox_new(FALSE, 3);
gtk_container_add(GTK_CONTAINER(hb), gtk_label_new("Background:"));
GtkWidget *cb = gtk_color_button_new();
gtk_container_add(GTK_CONTAINER(hb), cb);
gtk_container_add(GTK_CONTAINER(vb), hb);

Это обратная трассировка:

(gdb) backtrace 
#0  0x00007ffff4d88052 in ?? () from /lib/libc.so.6
#1  0x00007ffff5304112 in g_strdup () from /lib/libglib-2.0.so.0
#2  0x00007ffff5bc799d in ?? () from /usr/lib/libgobject-2.0.so.0
#3  0x00007ffff5ba826c in g_object_new_valist ()
   from /usr/lib/libgobject-2.0.so.0
#4  0x00007ffff5ba84f1 in g_object_new () from /usr/lib/libgobject-2.0.so.0
#5  0x00007ffff78502d5 in gtk_button_new_from_stock ()
   from /usr/lib/libgtk-x11-2.0.so.0
#6  0x00007ffff787cc95 in gtk_dialog_add_button ()
   from /usr/lib/libgtk-x11-2.0.so.0
#7  0x00007ffff787cd60 in ?? () from /usr/lib/libgtk-x11-2.0.so.0
#8  0x00007ffff787cf60 in gtk_dialog_new_with_buttons ()
   from /usr/lib/libgtk-x11-2.0.so.0
#9  0x0000000000402bb9 in show_settings_dialog () at settings.c:24
#10 0x0000000000403328 in main (argc=1, argv=0x7fffffffe2b8) at gatotray.c:286

... settings.c: 24 - это точно первая строка, указанная выше, похоже, что "gtk_dialog_new_with_buttons" - виновник ...

Версии:
gcc: 4.4.3
GTK +: 2.20.1

Кстати, забыл упомянуть, что комментирование определенных строк после конфликтного вызова предотвращает его возникновение.В частности, строка с "gtk_container_add (GTK_CONTAINER (hb), cb);"

Я перепробовал почти все подходящие комбинации GtkTypes / GTK_MACROS, без разницы.

1 Ответ

3 голосов
/ 02 февраля 2011

Короче говоря: используйте NULL , когда в руководстве написано NULL , а не просто 0 !

(сЯ не могу выбрать комментарии в качестве ответа, я сам пишу ответ, отдавая должное полезным комментариям ...)

Документация GTK + гласит:

GtkWidget*
gtk_dialog_new_with_buttons (const gchar    *title,
                             GtkWindow      *parent,
                             GtkDialogFlags  flags,
                             const gchar    *first_button_text,
                         ...);

title : Title of the dialog, or NULL. allow-none.
parent : Transient parent of the dialog, or NULL. allow-none.
flags : from GtkDialogFlags
first_button_text : stock ID or text to go in first button, or NULL. allow-none.
... : response ID for first button, then additional buttons, ending with NULL

Но я был ленив в ту ночь и набрал просто '0', где ожидалось NULL:

settings_dialog = GTK_DIALOG(gtk_dialog_new_with_buttons("gatotray Settings"
    , NULL, 0, GTK_STOCK_CANCEL, FALSE, GTK_STOCK_SAVE, TRUE, 0));

... Не замечая, что NULL - это указатель, который в моей 64-битной системе 64-битныйwide, тогда как 0 - это 32-разрядное целое число ...

Кроме того, похоже, что в списке аргументов переменной компилятор не смог обнаружить несоответствие: код скомпилирован спокойно с -Wall.

Как Myforwik предложил и Havoc P дополнительно пояснил, используя «NULL» вместо «0», чтобы устранить проблему.Спасибо, ребята!

Для записи я выполнил тестовую компиляцию в 32-битном режиме, где NULL также 32-битный, и в этом случае не было segfault.Это все еще неверно, так как документация достаточно ясна, и NULL не равен 0, независимо от того, что когда-либо говорили члены C ++!; -)

...