GTK +程序的分段错误

时间:2012-02-14 13:51:19

标签: c gtk segmentation-fault

我正在尝试使用我在gtkforums.com工作时找到的poppler和cairo来举例说明一个简单的 GTK + viewer 。但是我遇到了分段错误(我使用 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 个答案:

答案 0 :(得分:1)

基于您的评论(“无法访问地址0x0处的内存”),程序显示函数失败,但您没有检查函数的返回值以确保它不是使用前NULL

纯粹基于上面的代码示例,第一种情况是gtk_window_new失败;那么g_signal_connect和其他函数不能合理地使用win值。

当我编译片段时,它编译好没有警告,并正确执行。有关于PDF文档的poppler错误消息,但它与您的问题无关。

所以你的问题可能在其他地方(不在所包含的例子中)或一个微不足道的错误。

答案 1 :(得分:1)

获取更多信息的一种方法是在调试器中的g_log上设置断点,并获得警告/严重的回溯。通过回溯,您将能够看到您的代码究竟在哪里调用失败的gtk +函数。