简体   繁体   English

c / gtk + 3程序中的段错误

[英]segfault in c/gtk+3 program

Structs defined inside the header: 标头中定义的结构:

struct info{
    gint mode, isSignalActivate;
    gchar *filename;
    GtkWidget *pwdEntry, *pwdReEntry, *mainwin, *dialog, *file_dialog;
};
extern struct info s_Info;

struct hashes{
    gchar *filename;
    GtkWidget *entryMD5, *entryS1, *entryS256, *entryS512, *entryWhir, *entryRMD;
    GtkWidget *checkMD5, *checkS1, *checkS256, *checkS512, *checkWhir, *checkRMD;
};
extern struct hashes s_HashType;

and the main part of the program: 该程序的主要部分:

int main(int argc, char **argv){
    if(!gcry_check_version(GCRYPT_MIN_VER)){
        fputs("libgcrypt min version required: 1.5.0\n", stderr);
        return -1;
    }
    gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0);
    gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);

    GtkApplication *app;
    int status;

    app = gtk_application_new ("org.gtk.polcrypt",G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);
    return status;
}

static void startup (GtkApplication *application, gpointer user_data __attribute__ ((unused)))
{
  static const GActionEntry actions[] = {
    { "about", about },
    { "quit", quit }
  };

  GMenu *menu;

  g_action_map_add_action_entries (G_ACTION_MAP (application), actions, G_N_ELEMENTS (actions), application);

  menu = g_menu_new ();
  g_menu_append (menu, "About", "app.about");
  g_menu_append (menu, "Quit",  "app.quit");
  gtk_application_set_app_menu (application, G_MENU_MODEL (menu));
  g_object_unref (menu);
}

static void activate (GtkApplication *app, gpointer user_data __attribute__ ((unused)))
{
    GtkWidget *butHa, *grid;
    struct info s_Info;

    s_Info.mainwin = gtk_application_window_new(app);
    gtk_window_set_application (GTK_WINDOW (s_Info.mainwin), GTK_APPLICATION (app));
    gtk_window_set_position(GTK_WINDOW(s_Info.mainwin), GTK_WIN_POS_CENTER);
    gtk_window_set_title(GTK_WINDOW(s_Info.mainwin), "PolCrypt");
    gtk_window_set_resizable(GTK_WINDOW(s_Info.mainwin), FALSE);
    gtk_container_set_border_width(GTK_CONTAINER(s_Info.mainwin), 10);

    butHa = gtk_button_new_with_label("Compute Hash");
    g_signal_connect(butHa, "clicked", G_CALLBACK (is_hash), &s_Info);

    grid = gtk_grid_new();
    gtk_container_add(GTK_CONTAINER(s_Info.mainwin), grid);
    gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
    gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
    gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 5);

    //numero colonna, numero riga, colonne da occupare, righe da occupare. Colonne e righe sono aggiunte automaticamente
    gtk_grid_attach(GTK_GRID(grid), butHa, 0, 0, 5, 1);

    gtk_widget_show_all(s_Info.mainwin);
}

static void is_hash(GtkWidget *ignored __attribute__ ((unused)), struct info *s_Info){
    s_Info->mode = 3;
    file_dialog(s_Info);
}

static void file_dialog(struct info *s_Info){
    s_Info->file_dialog =  gtk_file_chooser_dialog_new("Choose File", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, ("_Cancel"), GTK_RESPONSE_CANCEL, ("_Ok"), GTK_RESPONSE_ACCEPT, NULL);
    if (gtk_dialog_run (GTK_DIALOG (s_Info->file_dialog)) == GTK_RESPONSE_ACCEPT){
        s_Info->filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (s_Info->file_dialog));
        if(s_Info->mode == 3){
            select_hash_type(s_Info);
            g_free (s_Info->filename);
        }
    }
    gtk_widget_destroy (s_Info->file_dialog);
}

static void select_hash_type(struct info *s_InfoHash){
    gtk_widget_hide(GTK_WIDGET(s_InfoHash->file_dialog));
    struct hashes s_HashType;
    GtkWidget *content_area, *grid2;
    s_InfoHash->dialog = gtk_dialog_new_with_buttons ("Select Hash", NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "_Quit", GTK_RESPONSE_CLOSE, NULL);
    content_area = gtk_dialog_get_content_area (GTK_DIALOG (s_InfoHash->dialog));

    s_HashType.checkMD5 = gtk_check_button_new_with_label("MD5");

    s_HashType.entryMD5 = gtk_entry_new();

    gtk_editable_set_editable(GTK_EDITABLE(s_HashType.entryMD5), FALSE);

    gtk_widget_set_size_request(s_InfoHash->dialog, 250, 150); // richiedo una grandezza minima

    grid2 = gtk_grid_new();
    gtk_grid_set_row_homogeneous(GTK_GRID(grid2), TRUE); // righe stessa altezza
    gtk_grid_set_column_homogeneous(GTK_GRID(grid2), TRUE); // colonne stessa larghezza
    gtk_grid_set_row_spacing(GTK_GRID(grid2), 5); // spazio fra le righe

    // numero colonna, numero riga, colonne da occupare, righe da occupare
    gtk_grid_attach(GTK_GRID(grid2), s_HashType.checkMD5, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid2), s_HashType.entryMD5, 2, 0, 6, 1);

    /* Add the grid, and show everything we've added to the dialog */
    gtk_container_add (GTK_CONTAINER (content_area), grid2);
    gtk_widget_show_all (s_InfoHash->dialog);

    s_HashType.filename = malloc(strlen(s_InfoHash->filename)+1);
    strcpy(s_HashType.filename, s_InfoHash->filename);

    g_signal_connect_swapped(s_HashType.checkMD5, "clicked", G_CALLBACK(compute_md5), &s_HashType);

    gint result = gtk_dialog_run(GTK_DIALOG(s_InfoHash->dialog));
    switch(result){
        case GTK_RESPONSE_CLOSE:
            gtk_widget_destroy(s_InfoHash->dialog);
            break;
    }
    free(s_HashType.filename);
}

My problem is that the program segfault when clicking on the "quit" button of s_InfoHash->dialog . 我的问题是,单击s_InfoHash->dialog的“退出”按钮时程序出现段s_InfoHash->dialog
Above there is the output of gdb. 上面是gdb的输出。

Program received signal SIGSEGV, Segmentation fault.
0x00000000009aa4f0 in ?? ()
(gdb) where
#0  0x00000000009aa4f0 in ?? ()
#1  0x00000000008f2290 in ?? ()
#2  0x00007fffffffd330 in ?? ()
#3  0x00000000007e0480 in ?? ()
#4  0x0000000000000188 in ?? ()
#5  0x0000000040000002 in ?? ()
#6  0x00007ffff5afbba9 in g_hash_table_lookup ()
   from /usr/lib64/libglib-2.0.so.0
#7  0x00007ffff5e17b7f in g_signal_emit_valist ()
   from /usr/lib64/libgobject-2.0.so.0
#8  0x00007ffff5e1881a in g_signal_emit () from /usr/lib64/libgobject-2.0.so.0
#9  0x00007ffff76be454 in ?? () from /usr/lib64/libgtk-3.so.0
#10 0x00007ffff75943dc in ?? () from /usr/lib64/libgtk-3.so.0
#11 0x00007ffff7595c2a in gtk_main_do_event () from /usr/lib64/libgtk-3.so.0
#12 0x00007ffff71ac522 in ?? () from /usr/lib64/libgdk-3.so.0
#13 0x00007ffff5b0bc66 in g_main_context_dispatch ()
   from /usr/lib64/libglib-2.0.so.0
#14 0x00007ffff5b0bfb8 in ?? () from /usr/lib64/libglib-2.0.so.0
#15 0x00007ffff5b0c05c in g_main_context_iteration ()
   from /usr/lib64/libglib-2.0.so.0
#16 0x00007ffff60d9eec in g_application_run () from /usr/lib64/libgio-2.0.so.0
#17 0x0000000000403339 in main (argc=1, argv=0x7fffffffd878)
    at src/gtk3/main-gui.c:35

This thing is driving me crazy because i cannot find what is causing the segfault... (i know that gdb say gtk_application_run (#17) but what does this mean? How can i debug and fix this thing?) 这件事使我发疯,因为我找不到导致段错误的原因...(我知道gdb说gtk_application_run (#17)但这是什么意思?我该如何调试和修复此问题?)

I'm using GCC 4.8.1 and GTK+ 3.10 我正在使用GCC 4.8.1和GTK + 3.10

离开activate()之后s_Info确实不存在,因此无论何时发出信号,您都在访问无效的内存块(以前由s_Info占用并由&s_Info ,您将其作为user_data传递给信号回调)

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

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