2012-02-14 3 views
1

Я пытаюсь сделать пример простого GTK + viewer с использованием poppler и cairo, который я нашел в gtkforums.com. Однако я получаю ошибку сегментации (я использую anjuta).Ошибка сегментации в программе GTK +

Когда я использую отладчик я получаю это:

ID: 1 Файл: /usr/lib/i386-linux-gnu/libgdk-x11-2.0.so.0 Line: 0 Функция : ?? Адрес: 0x1d3f16 (не думаю, что дело в любом случае)

терминал сообщение во время отладки:

Debug Terminal for the process: ------------------------------- &"warning: GDB: Failed to set controlling terminal: Operation not permitted\n"

GLib-GObject-WARNING **: cannot register existing type `GdkWindow'

GLib-GObject-CRITICAL **: g_object_new: assertion `G_TYPE_IS_OBJECT (object_type)' failed

Вот мой код:

#include <config.h> 
#include <glib/gi18n.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <glib.h> 
#include <gtk/gtk.h> 
#include <gdk/gdk.h> 
#include <cairo.h> 
#include <poppler.h> 

/* gcc `pkg-config --cflags --libs gtk+-2.0 poppler-glib` -o pdfviewer pdfviewer.c */ 

static PopplerDocument* doc; 
static PopplerPage* page; 

static void 
on_destroy(GtkWidget* w, gpointer data) { 
    gtk_main_quit(); 
} 

static gboolean 
on_expose(GtkWidget* w, GdkEventExpose* e, gpointer data) { 
    cairo_t* cr; 
    cr = gdk_cairo_create(w->window); 
    poppler_page_render(page, cr); 
    cairo_destroy(cr); 
    return FALSE; 
} 

int main(int argc, char* argv[]) { 
    GtkWidget* win; 
    GError* err = NULL; 

    gtk_init(&argc, &argv); 

    doc = poppler_document_new_from_file("file:///home/user/test.pdf", NULL, &err); 
    if (!doc) { 
     printf("%s\n", err->message); 
     g_object_unref(err); 
     return 2; 
    } 

    page = poppler_document_get_page(doc, 0); 
    if(!page) { 
     printf("Could not open first page of document\n"); 
     g_object_unref(doc); 
     return 3; 
    } 

    int pages = poppler_document_get_n_pages(doc); 
    printf("There are %d pages in this pdf.\n", pages); 

    win = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    g_signal_connect(G_OBJECT(win), "destroy",  G_CALLBACK(on_destroy), NULL); 
    g_signal_connect(G_OBJECT(win), "expose-event", G_CALLBACK(on_expose), NULL); 
    gtk_widget_set_app_paintable(win, TRUE); 
    gtk_widget_show_all(win); 

    gtk_main(); 

    g_object_unref(page); 
    g_object_unref(doc); 

    return 0; 
} 
+0

Можете ли вы пройти через свой отладчик и рассказать нам о линии, где возникает ошибка seg? Из этого кода есть несколько мест, которые могут произойти. –

+0

Убедитесь, что вы создали свою программу с включенной отладочной информацией, чтобы отладчик мог правильно рассказать вам, где он сбой. – unwind

+0

Я не могу найти способ скопировать все сообщения отладчика, но вот ошибка: ошибка, msg = «Невозможно получить доступ к памяти по адресу 0x0» – Rrjrjtlokrthjji

ответ

1

Основываясь на ваш комментарий его («не может получить доступ к память по адресу 0x0 «) появляется, что у программы есть функция, которая терпит неудачу, но вы не проверили возвращаемое значение функции, чтобы убедиться, что это не NULL до usin g это.

Основано исключительно на примере кода выше первого случая, если бы gtk_window_new не удалось; то g_signal_connect и другие функции не могут использовать значение win разумно.

Когда я скомпилировал фрагмент, он скомпилирован без предупреждений и выполнен правильно. В документе PDF появилось сообщение об ошибке Poppler, но оно не имело отношения к вашим проблемам.

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

+0

очень странно, что он работает для вас, вот мои когда я пытаюсь запустить его и получить ошибку сегментации: GLib-GObject-WARNING **: невозможно зарегистрировать существующий тип 'GdkWindow ' GLib-GObject-CRITICAL **: g_object_new: не удалось выполнить утверждение' G_TYPE_IS_OBJECT (object_type)' – Rrjrjtlokrthjji

1

Один из способов получения дополнительной информации - установить точку останова на g_log в отладчике и получить обратную сторону предупреждения/критического значения. С помощью backtrace вы сможете увидеть, где именно ваш код вызывает функцию gtk +, которая не работает.

+0

как я могу это сделать в anjuta IDE? – Rrjrjtlokrthjji

+0

Не знаете, как это сделать в Anjuta, но в командной строке gdb вы должны написать 'break g_log'. –

Смежные вопросы