Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Segfault when linking Scale widget with Entry #161

Open
timholy opened this issue Aug 28, 2015 · 9 comments
Open

Segfault when linking Scale widget with Entry #161

timholy opened this issue Aug 28, 2015 · 9 comments

Comments

@timholy
Copy link
Member

timholy commented Aug 28, 2015

If I move the scale slowly, this works as intended. However, quick movement---or any movement, if I delete the @schedule---causes a segfault for me:

using Gtk.ShortNames

e = @Entry()
sc = @Scale(false, 1:10)
hbox = @Box(:v)
win = @Window(hbox, "Segfault")
push!(hbox, e)
push!(hbox, sc)

signal_connect(sc, "value-changed") do widget
    println("value-changed")
    adj = @Adjustment(sc)
    val = getproperty(adj, :value, Int)
    @schedule setproperty!(e, :text, string(val))
end

showall(win)

I also get the segfault if I use G_.value(sc) rather than getproperty.

@timholy
Copy link
Member Author

timholy commented Aug 28, 2015

Oh, and here's the backtrace:

signal (11): Segmentation fault
unknown function (ip: 0x7f5bfe964178)
g_signal_emit_valist at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so (unknown line)
g_signal_emit at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so (unknown line)
unknown function (ip: 0x7f5bfe957725)
g_object_notify at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so (unknown line)
g_closure_invoke at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so (unknown line)
unknown function (ip: 0x7f5bfe964557)
g_signal_emit_valist at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so (unknown line)
g_signal_emit at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so (unknown line)
unknown function (ip: 0x7f5bfdc25c54)
unknown function (ip: 0x7f5bfdc1c1ae)
g_closure_invoke at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so (unknown line)
unknown function (ip: 0x7f5bfe964afb)
g_signal_emit_valist at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so (unknown line)
g_signal_emit_by_name at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so (unknown line)
unknown function (ip: 0x7f5bfdc16d57)
gtk_entry_set_text at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 (unknown line)
g_object_set_property at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so (unknown line)
setproperty! at /home/tim/.julia/v0.4/Gtk/src/GLib/gvalues.jl:163
jl_apply_generic at /home/tim/src/julia/usr/bin/../lib/libjulia.so (unknown line)
anonymous at task.jl:67
unknown function (ip: 0x7f5e119d0b58)
unknown function (ip: (nil))
Segmentation fault (core dumped)

@timholy
Copy link
Member Author

timholy commented Aug 29, 2015

I wanted to check that I wasn't missing something, so here's a comparison C program (no segfault):

#include <gtk/gtk.h>
#include <stdio.h>

char lbl[255] = "howdy";

void set_entry(GtkWidget *widget, gpointer data)
{
    GtkAdjustment *adj;
    GtkEntry *entry;
    double val;
    char *lbl;

    adj = gtk_range_get_adjustment((GtkRange*) widget);
    val = gtk_adjustment_get_value(adj);
    sprintf(lbl, "%g", val);
    entry = (GtkEntry*) data;
    gtk_entry_set_text(entry, lbl);
}

int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *entry;
    GtkWidget *scale;
    GtkBox *vbox;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    vbox = (GtkBox*) gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
    entry = gtk_entry_new();
    scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 10, 1);
    gtk_entry_set_text((GtkEntry*)entry, lbl);

    gtk_container_add(GTK_CONTAINER(window), (GtkWidget*)vbox);
    gtk_box_pack_start(vbox, entry, FALSE, FALSE, 10);
    gtk_box_pack_start(vbox, scale, FALSE, FALSE, 10);

    g_signal_connect(window, "delete-event", G_CALLBACK (gtk_main_quit),
NULL);
    g_signal_connect(scale, "value-changed", G_CALLBACK (set_entry), entry);

    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}

@timholy
Copy link
Member Author

timholy commented Aug 29, 2015

No segfault if I use the more low-level approach:

function value_changed_cb(ptr::Ptr, entry)
    sc = convert(Scale, ptr)
    val = G_.value(sc)
    setproperty!(entry, :text, string(val))
    nothing
end

signal_connect(value_changed_cb, sc, "value-changed", Void, (), false, e)

@vtjnash
Copy link
Contributor

vtjnash commented Aug 30, 2015

this is most likely an issue with the julia option COPY_STACKS corrupting the stack. it looks like another redesign of the gtk callback handling may be in my future to work around that.

@timholy
Copy link
Member Author

timholy commented Aug 30, 2015

Joy joy. Meanwhile, no rush since I figured out a workaround that I'm quite content with.

@vtjnash
Copy link
Contributor

vtjnash commented Sep 24, 2015

While I think the real solution to this will be to merge #13099, I think a temporary solution would be to remove the g_siginterruptible from https://github.com/JuliaLang/Gtk.jl/blob/40f7442dea20919c5a7b137594fb6d7636fa2329/src/GLib/signals.jl#L91 and just avoid calling yield / print / async from inside any Gtk callback.

@bjarthur
Copy link
Member

what high-level Gtk functions call yield / print / async? i'd really like to upgrade my code from julia 0.3 to 0.4 and need to know more specifically what to avoid in callbacks. can i setproperty! or @Entry() or signal_connect or ccall((:gtk_combo_box_text_remove_all,libgtk)... ? i've stripped out everything else and it's still hanging or segfaulting. thanks.

@ma-laforge
Copy link
Contributor

I encountered a similar problem when setproperty! is used within a signal handler...
...but it appears to only be an issue in Windows (works fine for Julia v0.4.2 on Linux).
(Bug found: Windows/Julia v0.4.3/Gtk+ 3 v0.9.3).

The following code consistently crashes when I press a key:

using Gtk
_Gtk = Gtk.ShortNames

type TestWindow
    widget::_Gtk.Window
    xscale::_Gtk.Adjustment
end

function handle_key(w::TestWindow, event::Gtk.GdkEventKey)
    @show event.keyval
    #setproperty crashes in Windows, for some reason:
    setproperty!(w.xscale, :value, Int(50))
    false #Do not keep processing?
end

#Create window with Scale object:
w_xscale = _Gtk.@Scale(false, 1:100)
    xscale = _Gtk.@Adjustment(w_xscale)
    setproperty!(xscale, :value, 1)
wnd = TestWindow(Gtk.@Window("Keytest", 640, 480, true), xscale)
    push!(wnd.widget, w_xscale)

#Add signal handler
conn = signal_connect(wnd.widget, "key_press_event") do widget, event
    handle_key(wnd, event)
end

showall(wnd.widget)

I don't know if this is the same issue. Just letting you know.

MA

@timholy
Copy link
Member Author

timholy commented May 10, 2016

The workaround in #161 (comment) is not sufficient; I tried it and still needed JuliaGtk/GtkUtilities.jl#7 to fix a segfault.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants