Сегфоут во время макроса GTK_TOGGLE_BUTTON ().Значения указателя изменились после изменения состояния флажка - PullRequest
1 голос
/ 10 мая 2019

Я пытаюсь создать программу с графическим интерфейсом, используя Glade и GTK + 3, чтобы записать набор и записать данные конфигурации в пользовательский микрочип.Я пытаюсь реализовать функцию для сохранения / загрузки предыдущих конфигураций в мой графический интерфейс.После сохранения в файл и загрузки некоторые из моих функций обратного вызова теперь вызывают сбой.Одним из примеров является обратный вызов для флажка «глобальное включение».

В настоящее время я пытаюсь прочитать данные из моего файла и использую эти данные для обновления состояния графического интерфейса пользователя (а также глобальные переменные, используемые для настройкиIC).Я обновляю свой флажок следующим образом:

/* Global widget handles */
GtkWidget* GEN_CB_h;
GtkWidget* Neg_Pol_CB_h;
GtkWidget* Save_File_Name_Box_h;
GtkWidget* Save_File_Button_h:
GtkWidget* Load_File_Button_h;
//more widgets here

/* Global configuration variables */
char gen;
char neg_pol;
//more variables here

/* Write data to a configuration file. */
void on_Save_Config_Button_clicked()
{
    GtkEntry* save_file = GTK_ENTRY(Save_File_Box_h);
    const gchar* filename = gtk_entry_get_text(save_file);

    FILE* fd = fopen((const char*)filename, "w");

    if(!fd)
    {
        perror("Failed to open file\n");
        exit(EXIT_FAILURE);
    }

    fwrite(&gen, sizeof(gen), 1, fd);
    fwrite(&neg_pol, sizeof(neg_pol), 1, fd);
    //more variables written here

    fclose(fd);

    g_printf("File saved to: %s\n", filename);
}


/* Load data from a stored configuration file */
void on_Load_File_Button_selection_changed()
{
    GtkFileChooser* file = GTK_FILE_CHOOSER(Load_File_Box_h);
    gchar* filename = gtk_file_chooser_get_filename(file);

    FILE* fd = fopen((const char*)filename, "r");

    if(!fd)
    {   
        perror("Failed to open file\n");
        exit(EXIT_FAILURE);
    }   

    fread(&gen, sizeof(gen), 1, fd);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(GEN_CB_h), gen); 

    fread(&neg_pol, sizeof(neg_pol), 1, fd);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(neg_pol_cb), neg_pol);

   /* read more data and update more GUI elements here */
}

/* Callback for negative polarity bit checkbox */
void on_Neg_Pol_CB_toggled()
{   
    GtkToggleButton* neg_pol_cb = GTK_TOGGLE_BUTTON(Neg_Pol_CB_h);

    neg_pol = (char)gtk_toggle_button_get_active(neg_pol_cb);
    printf("Neg pol toggled: %s\n", (neg_pol) ? "ON":"OFF");
}

/* Callback for global enable bit checkbox */
void on_GEN_CB_toggled()
{   
    printf("gen_cb = %p\n", GEN_CB_h); //print before cast for debugging
    GtkToggleButton* gen_cb = GTK_TOGGLE_BUTTON(GEN_CB_h);
    gen = (char)gtk_toggle_button_get_active(gen_cb);
    printf("GEN toggled: %s\n", (gen) ? "ON":"OFF");
}

int main(int argc, char *argv[])
{
    GtkBuilder      *builder;
    GtkWidget       *window;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, "CFD.glade", NULL);

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));

    GEN_CB_h = GTK_WIDGET(gtk_builder_get_object(builder, "GEN_CB"));
    Neg_Pol_CB_h = GTK_WIDGET(gtk_builder_get_object(builder, "Neg_Pol_CB"));

    Save_File_Box_h = GTK_WIDGET(gtk_builder_get_object(builder, "Save_File_Name_Box"));
    Load_File_Box_h = GTK_WIDGET(gtk_builder_get_object(builder, "Load_File_Button"));
    Save_File_Button_h = GTK_WIDGET(gtk_builder_get_object(builder, "Save_Config_Button"));

    //create more widgets here 

    gen = 1;
    neg_pol = 0; //positive polarity

    //set more variables here

    gtk_builder_connect_signals(builder, NULL);
    printf("connect returned\n");

    g_object_unref(builder);
    printf("unref returned\n");

    gtk_widget_show(window);
    printf("show returned\n");
    gtk_main();

    return 0;
}

Проблема, с которой я сталкиваюсь, заключается в том, что после загрузки новой конфигурации (т. Е. Запуска моего обратного вызова Load_File_Button) мой обратный вызов GEN_CB вызывает ошибку сегмента в этой строке:

GtkToggleButton* gen_cb = GTK_TOGGLE_BUTTON(GEN_CB_h);

Я использовал GDB, чтобы увидеть причину segfault, и сообщил об этом как:

Thread 1 "cfd_gui" received signal SIGSEGV, Segmentation fault.
0x00007ffff7395ea0 in g_type_check_instance_cast () from /usr/lib/libgobject-2.0.so.0

Я также включил оператор printf, чтобы проверить, происходит ли что-нибудь с указателем между нагрузкамии обнаружил, что значение указателя изменяется после выполнения этой строки:

gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(GEN_CB_h), gen); 

Я все еще новичок в GTK3, поэтому, возможно, я использую что-то неправильно, но не смог выяснить это.Вот выходные данные моих операторов отладки printf:

gen_cb = 0x55cd1aa04240
GEN toggled: OFF
Loaded configuration from file: /home/borabutt/github/CFD-RPI-Test/src/C/gui/test.dat
gen_cb = 0x55ea7bb68240

Первая строка показывает указатель на GEN_CB_h до загрузки данных конфигурации.Тогда, как ясно видно, значение указателя изменяется после загрузки данных конфигурации.Мои исследования показали, что это изменение происходит после установки состояния флажка, как показано выше.

Мне нужно иметь возможность обновлять состояние многих флажков и комбинированных окон, чтобы правильно отражать загруженное состояние из файла.Прямо сейчас графический интерфейс работает полностью, пока я не загружаю данные из файла.Любая помощь и понимание приветствуется.

РЕДАКТИРОВАТЬ:

Я должен отметить, что я включил обратный вызов Neg_Pol_CB, потому что эта функция не вызывает segfault после загрузки данных конфигурации, в то время какобратный вызов GEN_CB делает.

1 Ответ

0 голосов
/ 11 мая 2019

Я понял это. Оказывается, код, который я редактировал / собирал на своем ноутбуке, устарел по сравнению с тем, что было на моем github (код github - это то, что я выложил здесь). Я думал, что вытащил, но, видимо, нет. У меня была строка кода, где я записывал / считывал файл неверного размера элемента данных:

fwrite(&gen, sizeof(&gen), 11, fd);
...
fread(&gen, sizeof(&gen), 11, fd);

Две ошибки, я случайно читал / писал sizeof(&gen) вместо sizeof(gen), и я также читал / записывал 11 элементов данных вместо одного. Это заставило меня переписать некоторые другие указатели, очевидно. Я буду работать над обновлением всех моих обратных вызовов, чтобы они соответствовали сигнатурам, но теперь все это работает.

...