简体   繁体   English

单击 GtkButton 时出现分段错误

[英]segmentation fault on clicking a GtkButton

Depending on the location of the init_prog(user) call in my program I get a segmentation fault, I don't understand the reason.根据我的程序中init_prog(user)调用的位置,我遇到了分段错误,我不明白原因。 If I put the call in the start() callback function after clicking btn_go it crashes:如果我在单击btn_go后将调用放入start()回调 function 中,则会崩溃:

Thread 1 "./a.out" received signal SIGSEGV, Segmentation fault. 0x00007ffff7812526 in gdk_window_get_display (window=0x55555555b1c0) at../../../../gdk/gdkwindow.c:2303 2303../../../../gdk/gdkwindow.c: No such file or directory.

This is the back trace:这是回溯:

Thread 1 "./a.out" received signal SIGSEGV, Segmentation fault.
0x00007ffff7812526 in gdk_window_get_display (window=0x55555555b1c0) at ../../../../gdk/gdkwindow.c:2303
2303    ../../../../gdk/gdkwindow.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7812526 in gdk_window_get_display (window=0x55555555b1c0) at ../../../../gdk/gdkwindow.c:2303
#1  0x00007ffff78022ce in event_get_display (event=0x7fffe800add0) at ../../../../gdk/gdkevents.c:457
#2  0x00007ffff78022ce in gdk_event_free (event=0x7fffe800add0) at ../../../../gdk/gdkevents.c:839
#3  0x00007ffff783311a in gdk_event_source_dispatch
    (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>)
    at ../../../../../gdk/x11/gdkeventsource.c:369
#4  0x00007ffff730cf2e in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5  0x00007ffff730d1c8 in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#6  0x00007ffff730d4c2 in g_main_loop_run () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#7  0x00007ffff7affb15 in gtk_main () at ../../../../gtk/gtkmain.c:1323
#8  0x0000555555556da1 in create_window () at gui.c:118
#9  0x000055555555644d in main (argc=1, argv=0x7fffffffe328) at main.c:26

This is the code:这是代码:

#include <glib.h>
#include <stdio.h>
#include <gtk/gtk.h>

void start (GtkWidget *widget, struct prog_data *user);

void create_window() {

    GtkWidget *window;
    GtkWidget *headbar;
    GtkWidget *vbox;
    GtkWidget *hbox_superself;
    GtkWidget *hbox_my_struct;
    GtkWidget *hbox_self;
    GtkWidget *btn_about;
    GtkWidget *btn_go;
    GtkWidget *evnt_box[3];

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    headbar = gtk_header_bar_new();
    btn_about = gtk_button_new_with_label("About");
    btn_go = gtk_button_new_with_label("Start");
    evnt_box[0] = gtk_evnt_box_new ();
    evnt_box[1] = gtk_evnt_box_new ();
    evnt_box[2] = gtk_evnt_box_new ();
    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
    hbox_superself = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 35);
    hbox_my_struct = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
    hbox_self = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 35);
    my_struct.label_user[USR0] = gtk_label_new ("0");
    my_struct.label_user[USR1] = gtk_label_new ("0");
    my_struct.lbl_pings_left = gtk_label_new ("");

    my_struct.img_show[0] = gtk_image_new ();
    my_struct.img_show[1] = gtk_image_new ();

    my_struct.image_deck_pile = gtk_image_new_from_file ("1.png");

my_struct.self_image[0] = gtk_image_new_from_file ("2.png");
my_struct.self_image[1] = gtk_image_new_from_file ("2.png");
my_struct.self_image[2] = gtk_image_new_from_file ("2.png");

    my_struct.image_orca = gtk_image_new ();

    my_struct.super_self[0] = gtk_image_new();
    my_struct.super_self[1] = gtk_image_new();
    my_struct.super_self[2] = gtk_image_new();

    gtk_header_bar_set_title (GTK_HEADER_BAR (headbar), "Orca");
    gtk_window_set_title (GTK_WINDOW (window), "Orca");    
    gtk_window_set_titlebar (GTK_WINDOW (window), headbar);
    gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headbar), TRUE);
    gtk_window_maximize (GTK_WINDOW (window));

    GtkCssProvider *css_provider = gtk_css_provider_new();
    gtk_css_provider_load_from_path (css_provider, "style.css", NULL);

    GdkScreen *myScreen = gdk_screen_get_default();
    gtk_style_context_add_provider_for_screen (myScreen, GTK_STYLE_PROVIDER (css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER);

    struct prog_data user[2];

    gtk_container_add(GTK_CONTAINER (headbar), btn_about);
    gtk_container_add(GTK_CONTAINER (window), vbox);
    gtk_container_add(GTK_CONTAINER (vbox), hbox_superself);
    gtk_container_add(GTK_CONTAINER (vbox), hbox_my_struct);
    gtk_container_add(GTK_CONTAINER (vbox), hbox_self);
    gtk_container_add(GTK_CONTAINER (hbox_superself), my_struct.self_image[0]);
    gtk_container_add(GTK_CONTAINER (hbox_superself), my_struct.self_image[1]);
    gtk_container_add(GTK_CONTAINER (hbox_superself), my_struct.self_image[2]);
    gtk_container_add(GTK_CONTAINER (hbox_superself), my_struct.label_user[USR1]);
    gtk_container_add(GTK_CONTAINER (hbox_my_struct), my_struct.image_orca);
    gtk_container_add(GTK_CONTAINER (hbox_my_struct), my_struct.image_deck_pile);
    gtk_container_add(GTK_CONTAINER (hbox_my_struct), my_struct.lbl_pings_left);
    gtk_container_add(GTK_CONTAINER (hbox_my_struct), btn_go);
    gtk_container_add(GTK_CONTAINER (hbox_my_struct), my_struct.img_show[0]);
    gtk_container_add(GTK_CONTAINER (hbox_my_struct), my_struct.img_show[1]);
    gtk_container_add(GTK_CONTAINER (hbox_self), evnt_box[0]);
    gtk_container_add(GTK_CONTAINER (hbox_self), evnt_box[1]);
    gtk_container_add(GTK_CONTAINER (hbox_self), evnt_box[2]);
    gtk_container_add(GTK_CONTAINER (evnt_box[0]), my_struct.super_self[0]);
    gtk_container_add(GTK_CONTAINER (evnt_box[1]), my_struct.super_self[1]);
    gtk_container_add(GTK_CONTAINER (evnt_box[2]), my_struct.super_self[2]);
    gtk_container_add(GTK_CONTAINER (hbox_self), my_struct.label_user[USR0]);

    GtkStyleContext *context1;                                      
    context1 = gtk_widget_get_style_context(hbox_self);         
    gtk_style_context_add_class(context1, "my_hbox_self");

    GtkStyleContext *context2;
    context2 = gtk_widget_get_style_context(hbox_superself);    
    gtk_style_context_add_class(context2, "my_hbox_superself");

    GtkStyleContext *context3;
    context3 = gtk_widget_get_style_context(hbox_my_struct);    
    gtk_style_context_add_class(context3, "my_hbox_my_struct");

    gtk_widget_set_name (my_struct.img_show[0], "user1");

    g_signal_connect (btn_about, "clicked", G_CALLBACK (activate_about), NULL);
    g_signal_connect (G_OBJECT (evnt_box[0]), "button_press_event", G_CALLBACK (ping1_clicked), user);
    g_signal_connect (G_OBJECT (evnt_box[1]), "button_press_event", G_CALLBACK (ping2_clicked), user);
    g_signal_connect (G_OBJECT (evnt_box[2]), "button_press_event", G_CALLBACK (ping3_clicked), user);
    g_signal_connect (G_OBJECT (btn_go), "button_press_event", G_CALLBACK (start), user);
    g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);

    gtk_widget_show_all (window);

    gtk_main();
}

void start (GtkWidget *btn_go, struct prog_data *user) {
    gtk_widget_hide(btn_go);
    printf("Right\n");
    init_prog(user);    
}

If I move the call init_prog(user) in the create_window() function after gtk_widget_show_all (window);如果我在gtk_widget_show_all (window);之后移动 create_window( create_window() function 中的调用init_prog(user) ); , I do not experience any crash. ,我没有遇到任何崩溃。 I've tested the init_prot(user) function separately and it works well.我已经单独测试了init_prot(user) function 并且效果很好。

You are cheating GTK by providing an incorrect callback function.您通过提供不正确的回调 function 来欺骗 GTK。

The manual tells us how your callback shall look like for "button_press_event" : 手册告诉我们你的回调应该是怎样的"button_press_event"

gboolean
user_function (GtkWidget *widget,
               GdkEvent  *event,
               gpointer   user_data)

You access event pointer and treat is as user_data pointer.您访问event指针并将其视为user_data指针。 That causes undefined behaviour.这会导致未定义的行为。 You also fail to provide mandatory boolean return value.您也未能提供强制性 boolean 返回值。

You must adjust the signature of your callback function to match the requirements.您必须调整回调 function 的签名以符合要求。

Or maybe you might change to use "clicked" or "pressed" event of the button widget instead of the "button-pressed-event" .或者,您可能会更改为使用按钮小部件的"clicked""pressed"事件,而不是"button-pressed-event"

You also should check the other callback functions that were not present in the question for the same error.您还应该检查问题中不存在的其他回调函数是否存在相同的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM