Re: Segmentation fault when passing Poppler objects

2018-11-06 Thread Emmanuele Bassi via gtk-app-devel-list
On Tue, 6 Nov 2018 at 09:55, Радомир Хаџић via gtk-app-devel-list <
gtk-app-devel-list@gnome.org> wrote:

> Hi. I get segmentation fault if I try to access a Poppler object whose
> pointer is passed through g_signal_connect. There is no such problem
> with normal pointers, though.


This:


> void draw_cb(GtkWidget *drawing_area, struct Colors *colors)
>

Is *not* the signature for a GtkWidget::draw signal callback.

The signature is:

  gboolean (* draw) (GtkWidget *widget, cairo_t *context, gpointer
user_data);


0x5571faa9c6e0

> 0x5571fac68200
> current colors are:
> red 0.00
> green 0.00
> blue 0.00
> As we can see, colors in main and colors in draw_cb have different
> values, but this doesn't stop us from accessing the object (I wonder
> how this works, though it's not important in this case).
>

It "works" because you're getting passed a pointer to a memory area, and
you're trying to access it by 3 `sizeof(double)` offsets; the cairo_t
structure is large enough to accommodate those accesses without generating
a segmentation fault, but of course cairo_t does not contain 3 doubles at
the very beginning of its structure, so you're getting garbage that C
helpfully translates to a double representation. I also assume that you're
running on a 64 bit architecture, because if you tried the same of 32 bits
archs, you'd very much get a segmentation fault.

Of course, this will never work for a PopplerDocument instance, because
you're not trying to access the first `3 * sizeof(double)` bytes of it:
you're calling a Poppler function, which expects a PopplerDocument
instance, instead of a cairo_t one:

void doc_cb(GtkWidget *drawing_area, PopplerDocument *doc)
> {
> g_print("%p\n", doc);
> g_print("%d\n", poppler_document_get_n_pages(doc));
> }
>
>
Which is why you're getting a segmentation fault.

I strongly encourage you to read the GTK API reference:

https://developer.gnome.org/gtk3/stable/GtkWidget.html#GtkWidget-draw

In general, you should *always* read the documentation for each signal
you're using, to know the signature of the callback associated to the
signal. The signal machinery disables a lot of the type safety at compile
time in order to allow generic functions to be invoked without ad hoc
emitters.

Ciao,
 Emmanuele.

-- 
https://www.bassi.io
[@] ebassi [@gmail.com]
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Segmentation fault when passing Poppler objects

2018-11-06 Thread Радомир Хаџић via gtk-app-devel-list
Hi. I get segmentation fault if I try to access a Poppler object whose
pointer is passed through g_signal_connect. There is no such problem
with normal pointers, though.

For example, if I run the following code...
#include 

struct Colors
{
double red;
double green;
double blue;
};

void draw_cb(GtkWidget *drawing_area, struct Colors *colors)
{
g_print("%p\n", colors);
g_print("current colors are:\n");
g_print("red %f\n", colors->red);
g_print("green %f\n", colors->green);
g_print("blue %f\n", colors->blue);
// draw something
}

void main()
{
gtk_init(NULL, NULL);

struct Colors *colors = (struct Colors *)
g_malloc(sizeof(struct Colors));
g_print("%p\n", colors);

GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
g_signal_connect(window, "delete-event",
G_CALLBACK(gtk_main_quit), NULL);

GtkWidget *drawing_area = gtk_drawing_area_new();
g_signal_connect(drawing_area, "draw", G_CALLBACK(draw_cb), colors);

gtk_container_add(GTK_CONTAINER(window), drawing_area);
gtk_widget_show_all(window);

gtk_main();

g_free(colors);
}
...this is the output I get.
0x5571faa9c6e0
0x5571fac68200
current colors are:
red 0.00
green 0.00
blue 0.00
As we can see, colors in main and colors in draw_cb have different
values, but this doesn't stop us from accessing the object (I wonder
how this works, though it's not important in this case).

Now let's consider the same case but using PopplerDocument* instead of
struct Colors*.
#include 
#include 

void doc_cb(GtkWidget *drawing_area, PopplerDocument *doc)
{
g_print("%p\n", doc);
g_print("%d\n", poppler_document_get_n_pages(doc));
}

void main()
{
gtk_init(NULL, NULL);

PopplerDocument *doc =
poppler_document_new_from_file("file:///tmp/test/mypdf.pdf", NULL,
NULL);
g_print("%p\n", doc);

GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), 
NULL);

GtkWidget *drawing_area = gtk_drawing_area_new();
g_signal_connect(drawing_area, "draw", G_CALLBACK(doc_cb), doc);

gtk_container_add(GTK_CONTAINER(window), drawing_area);
gtk_widget_show_all(window);

gtk_main();
}
Output:
0x5584e8573900
0x5584e813d180
Segmentation fault (core dumped)
Here we get segmentation fault, probably because doc in doc_cb is not
mapped to doc in main.

My question is obviously how can I work around this issue and get
valid PopplerDocument object in main? I tried passing  as
PopplerDocument** but it did not work.
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list