Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C GTK和x2B处的分段故障;程序_C_Gtk_Segmentation Fault - Fatal编程技术网

C GTK和x2B处的分段故障;程序

C GTK和x2B处的分段故障;程序,c,gtk,segmentation-fault,C,Gtk,Segmentation Fault,我正在尝试使用我在工作中发现的poppler和cairo制作一个简单的GTK+查看器的示例。但是,我遇到了一个分段错误(我使用了anjuta) 当我使用调试器时,我得到以下信息: ID:1 文件:/usr/lib/i386 linux gnu/libgdk-x11-2.0.so.0 行:0 功能:?? 地址:0x1d3f16(无论如何都不认为这很重要) 调试时的终端消息: 进程的调试终端: -------------------------------&“警告:GDB:设置控制终端失败:不允许操

我正在尝试使用我在工作中发现的poppler和cairo制作一个简单的GTK+查看器的示例。但是,我遇到了一个分段错误(我使用了anjuta

当我使用调试器时,我得到以下信息:

ID:1 文件:/usr/lib/i386 linux gnu/libgdk-x11-2.0.so.0 行:0 功能:?? 地址:0x1d3f16(无论如何都不认为这很重要)

调试时的终端消息:

进程的调试终端: -------------------------------&“警告:GDB:设置控制终端失败:不允许操作\n”

GLib GObject警告**:无法注册现有类型“GdkWindow”

GLib GObject CRITICAL**:g_object_new:assertion`g_TYPE_IS_object (对象类型)“”失败

这是我的密码:

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*gcc`pkg config--cflags--libs gtk+-2.0 poppler glib`-o pdfviewer pdfviewer.c*/
静态文档*doc;
静态页面*页面;
静态空隙
on_销毁(GtkWidget*w,gpointer数据){
gtk_main_quit();
}
静态gboolean
on_expose(GtkWidget*w、GdkEventExpose*e、gpointer数据){
开罗*cr;
cr=gdk\u cairo\u create(w->window);
poppler_页面_呈现(页面,cr);
开罗大学(cr);
返回FALSE;
}
int main(int argc,char*argv[]){
GtkWidget*赢;
GError*err=NULL;
gtk_init(&argc,&argv);
doc=poppler\u文件\u新文件\u文件(“file:///home/user/test.pdf“,NULL,&err);
如果(!doc){
printf(“%s\n”,错误->消息);
g_object_unref(err);
返回2;
}
page=poppler\u document\u get\u page(doc,0);
如果(!第页){
printf(“无法打开文档的第一页\n”);
g_object_unref(doc);
返回3;
}
int pages=poppler\u document\u get\u n\u pages(doc);
printf(“此pdf中有%d页。\n”,页);
win=gtk_窗口_新建(gtk_窗口_顶级);
g_信号连接(g_对象(win),“销毁”,g_回调(on_销毁),NULL);
g_信号连接(g_对象(win),“暴露事件”,g_回调(on_暴露),NULL);
gtk_widget_set_app_paintable(赢,真);
gtk_widget_show_all(赢);
gtk_main();
g_object_unref(第页);
g_object_unref(doc);
返回0;
}

根据您的注释(“无法访问地址0x0处的内存”)显示该程序有一个失败的函数,但在使用该函数之前,您没有检查该函数的返回值以确保它不为空

仅根据上面的代码示例,第一种情况是如果
gtk\u window\u new
失败;然后,
g\u信号\u连接
和其他功能无法明智地使用
win

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


因此,您的问题可能在其他地方(不在包含的示例中)或是一个小错误

获取更多信息的一种方法是在调试器中的g_日志上设置断点,并获取警告/关键事件的回溯。通过回溯,您将能够看到您的代码调用失败的gtk+函数的确切位置。

您能否通过调试器告诉我们seg故障发生的位置??从这段代码中,有几个地方可能会发生这种情况。请确保在生成程序时启用了调试信息,以便调试器可以正确地告诉您程序崩溃的位置。我似乎找不到复制所有调试器消息的方法,但错误如下:error,msg=“无法访问地址0x0处的内存”非常奇怪,它对您有效,当我尝试运行它并获得分段错误时,以下是我的终端错误:GLib GObject警告**:无法注册现有类型
GdkWindow'GLib GObject CRITICAL**:g_object_new:assertion
g_type_IS_object(object_type)'failed我如何在anjuta IDE中做到这一点?不确定如何在anjuta中做到这一点,但在命令行gdb中,您可以编写“breakg_log”。