pqiv icon indicating copy to clipboard operation
pqiv copied to clipboard

segfault while viewing live updating file

Open clemtaylor opened this issue 3 years ago • 4 comments

I have a program that is dumping jpg images to /tmp/stream#.jpg at ~30fps. It updates the file by writing to a temp file and then using renameat() to swap the new image in.

"pqiv /tmp/stream#.jpg" will play back the jpeg frames, not quite at 30fps (maybe 10-15), but after several minutes it segfaults. When I recompiled without the optimizer it seemed to take much longer to fail.

Thread 1 "pqiv" received signal SIGSEGV, Segmentation fault.
0x000000000040fea6 in window_draw_callback (widget=widget@entry=0x72e260, cr_arg=0x5e8e30, 
    user_data=<optimized out>) at .../pqiv.git/pqiv.c:5081
5081		if(is_current_file_loaded()) {
Missing separate debuginfos, use: dnf debuginfo-install libepoxy-1.5.7-1.fc34.x86_64 libgcrypt-1.9.3-2.fc34.x86_64
(gdb) where
#0  0x000000000040fea6 in window_draw_callback
    (widget=widget@entry=0x72e260, cr_arg=0x5e8e30, user_data=<optimized out>)
    at .../pqiv.git/pqiv.c:5081
#1  0x00007ffff7bd5327 in _gtk_marshal_BOOLEAN__BOXED
    (closure=0x4db8b0, return_value=0x7fffffffcfe0, n_param_values=<optimized out>, param_values=0x7fffffffd040, invocation_hint=<optimized out>, marshal_data=<optimized out>)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gtk/gtkmarshalers.c:83
#2  0x00007ffff7b7e9c3 in gtk_widget_draw_marshaller
    (closure=closure@entry=0x4db8b0, return_value=return_value@entry=0x7fffffffcfe0, n_param_values=n_param_values@entry=2, param_values=param_values@entry=0x7fffffffd040, invocation_hint=invocation_hint@entry=0x7fffffffcfc0, marshal_data=marshal_data@entry=0x0)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gtk/gtkwidget.c:947
#6  0x00007ffff70ed983 in <emit signal ??? on instance ???>
    (instance=instance@entry=0x72e260, signal_id=<optimized out>, detail=detail@entry=0)
    at ../gobject/gsignal.c:3553
    #3  0x00007ffff70cfc2f in g_closure_invoke
    (closure=0x4db8b0, return_value=0x7fffffffcfe0, n_param_values=2, param_values=0x7fffffffd040, invocation_hint=0x7fffffffcfc0) at ../gobject/gclosure.c:810
    #4  0x00007ffff70ebea6 in signal_emit_unlocked_R
    (node=<optimized out>, detail=detail@entry=0, instance=instance@entry=0x72e260, emission_return=emission_return@entry=0x7fffffffd160, instance_and_params=instance_and_params@entry=0x7fffffffd040)
    at ../gobject/gsignal.c:3741
    #5  0x00007ffff70ed2de in g_signal_emit_valist
    (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffd210) at ../gobject/gsignal.c:3507
#7  0x00007ffff7b8d962 in gtk_widget_draw_internal
    (widget=0x72e260, cr=0x5e8e30, clip_to_size=<optimized out>)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gtk/gtkwidget.c:7073
#8  0x00007ffff7b9aa00 in gtk_widget_render (widget=0x72e260, window=0x453760, region=<optimized out>)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gtk/gtkwidget.c:17606
#9  0x00007ffff7a4020b in gtk_main_do_event (event=<optimized out>)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gtk/gtkmain.c:1844
#10 gtk_main_do_event (event=<optimized out>)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gtk/gtkmain.c:1691
#11 0x00007ffff76f97d3 in _gdk_event_emit (event=0x7fffffffd4b0)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gdk/gdkevents.c:73
#12 _gdk_event_emit (event=0x7fffffffd4b0)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gdk/gdkevents.c:67
#13 0x00007ffff770c181 in _gdk_window_process_updates_recurse_helper
    (window=0x453760, expose_region=<optimized out>)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gdk/gdkwindow.c:3874
#14 0x00007ffff7711251 in gdk_window_process_updates_internal (window=0x453760)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gdk/gdkwindow.c:4020
#15 0x00007ffff7711448 in gdk_window_process_updates_with_mode
    (window=<optimized out>, recurse_mode=<optimized out>)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gdk/gdkwindow.c:4215
#16 0x00007ffff70ed83a in _g_closure_invoke_va
    (param_types=0x0, n_params=<optimized out>, args=0x7fffffffd760, instance=0x4894b0, return_value=0x0, closure=0x5dd3a0) at ../gobject/gclosure.c:873
#17 g_signal_emit_valist
    (instance=0x4894b0, signal_id=<optimized out>, detail=0, var_args=var_args@entry=0x7fffffffd760)
    at ../gobject/gsignal.c:3406
#18 0x00007ffff70ed983 in g_signal_emit
    (instance=instance@entry=0x4894b0, signal_id=<optimized out>, detail=detail@entry=0)
    at ../gobject/gsignal.c:3553
#19 0x00007ffff7706c9f in _gdk_frame_clock_emit_paint (frame_clock=0x4894b0)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gdk/gdkframeclock.c:657
#20 gdk_frame_clock_paint_idle (data=0x4894b0)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gdk/gdkframeclockidle.c:597
--Type <RET> for more, q to quit, c to continue without paging--
#21 0x00007ffff76f331d in gdk_threads_dispatch (data=data@entry=0x5d1740)
    at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gdk/gdk.c:769
#22 0x00007ffff6fd5d21 in g_timeout_dispatch
    (source=0x602cd0, callback=0x7ffff76f32f0 <gdk_threads_dispatch>, user_data=0x5d1740)
    at ../glib/gmain.c:4889
#23 0x00007ffff6fd54cf in g_main_dispatch (context=0x47e750) at ../glib/gmain.c:3337
#24 g_main_context_dispatch (context=0x47e750) at ../glib/gmain.c:4055
#25 0x00007ffff70294e8 in g_main_context_iterate.constprop.0
    (context=0x47e750, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>)
    at ../glib/gmain.c:4131
#26 0x00007ffff6fd4a93 in g_main_loop_run (loop=0x4eae50) at ../glib/gmain.c:4329
#27 0x00007ffff7a3647d in gtk_main () at /usr/src/debug/gtk3-3.24.29-1.fc34.x86_64/gtk/gtkmain.c:1329
#28 0x0000000000409b9e in main (argc=<optimized out>, argv=<optimized out>)
    at .../pqiv.git/pqiv.c:8229

gdb shows that current_file_node is valid, but current_file_node->data is null.

This is the current origin/master d2d7ebb

clemtaylor avatar Jul 09 '21 18:07 clemtaylor

Interesting.. thanks for the backtrace! A race condition in assigning the value, maybe? 🤔

phillipberndt avatar Jul 09 '21 19:07 phillipberndt

@clemtaylor Rather than /tmp/stream#.jpg you could try /run/user/1000/stream#.jpg (assuming your UID is 1000).

WinEunuuchs2Unix avatar Jul 10 '21 00:07 WinEunuuchs2Unix

@clemtaylor Rather than /tmp/stream#.jpg you could try /run/user/1000/stream#.jpg (assuming your UID is 1000).

In this case both /tmp and /run/user are tmpfs. The code that is writing the frames expects it to be tmpfs.

clemtaylor avatar Jul 10 '21 03:07 clemtaylor

It is possible that the error occurs when the window is mapped.

It had been running for a while without crashing (few minutes). I minimized it for a while (few more minutes) and then it crashed exactly when I unminimized it (I'm using xfwm4).

clemtaylor avatar Jul 10 '21 03:07 clemtaylor