Ошибка сегментации в программе GTK + - PullRequest
1 голос
/ 14 февраля 2012

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

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

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

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

Терминал отладки для процесса: ------------------------------- & "предупреждение: GDB: не удалось установить управляющий терминал: операция не разрешена \ n"

GLib-GObject-WARNING **: невозможно зарегистрировать существующий тип `GdkWindow '

GLib-GObject-CRITICAL **: g_object_new: утверждение `G_TYPE_IS_OBJECT (object_type) 'не удалось

Вот мой код:

#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;
}

Ответы [ 2 ]

1 голос
/ 16 февраля 2012

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

1 голос
/ 14 февраля 2012

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

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

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

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

...