Discussion:
segfault in external commands
Jim Hayward
2014-03-03 07:30:46 UTC
Permalink
Hi Olivier,

A segfault occurs if an external command doesn't exist. This appears to
possibly only happen if there is a statuscode_cb. child_watch_lcb()
correctly sees the issue, but doesn't prevent start_command_idle() from
being run. A simple solution with the existing code appears to be just
if status !=0 g_source_remove(ep->start_command_idle_id).

command_backend, started
create_commandstring, formatstring ' csstidy --preserve_css=true - '
seems OK
create_commandstring,is_local_non_modified=1, uri=0x885740, modified=0
create_commandstring, returning csstidy --preserve_css=true -
start_command_backend,commandstring= csstidy --preserve_css=true -
start_command_backend, pipe_in=1, pipe_out=1, include_stderr=0
start_command_backend, about to spawn process /bin/sh -c csstidy
--preserve_css=true -
Detaching after fork from child process 9489.
/bin/sh: csstidy: command not found
child_watch_lcb, child exited with status=32512
filter_statuscode_lcb, exitcode 32512
start_command_idle, creating channel_in from pipe
start_command_idle, begin=0, end=-1, add watch for channel_in
start_command_idle, created channel_out from pipe
start_command_idle, add watch for channel_out
externalp_unref, started for 0x15ac270, refount=3
start_command_write_lcb, started, still 653 bytes to go
start_command_write_lcb, 653 bytes written
start_command_write_lcb, finished, shutting down channel

Program received signal SIGPIPE, Broken pipe.
0x000000310340e81d in write () from /lib64/libpthread.so.0

(gdb) bt
#0 0x000000310340e81d in write () from /lib64/libpthread.so.0
#1 0x000000310588ae2c in g_io_unix_write ()
from /lib64/libglib-2.0.so.0
#2 0x000000310583c479 in g_io_channel_flush ()
from /lib64/libglib-2.0.so.0
#3 0x000000310583c882 in g_io_channel_shutdown ()
from /lib64/libglib-2.0.so.0
#4 0x00000000004528ff in start_command_write_lcb (channel=0x8d36d0,
condition=<optimized out>, data=0x15ac270) at external_commands.c:143
#5 0x00000031058492a6 in g_main_context_dispatch ()
from /lib64/libglib-2.0.so.0
#6 0x0000003105849628 in g_main_context_iterate.isra.24 ()
from /lib64/libglib-2.0.so.0
#7 0x0000003105849a3a in g_main_loop_run ()
from /lib64/libglib-2.0.so.0
#8 0x0000003b87537620 in gtk_dialog_run () from /lib64/libgtk-3.so.0
#9 0x00000000004467f6 in message_dialog_new (parent=0x8fa2e0,
type=<optimized out>, button=GTK_BUTTONS_CLOSE, primaryText=0x4861c4
"Command returned error code",
secondaryText=0x13a3a00 "The command csstidy --preserve_css=true -
exited with error code 32512. Probably this application is not installed
on your system.") at dialog_utils.c:698
#10 0x0000000000452eab in filter_statuscode_lcb (status=<optimized out>,
bfwin=<optimized out>, data=0x15ac270) at external_commands.c:746
#11 0x000000000045299a in child_watch_lcb (pid=9489, status=32512,
data=0x15ac270) at external_commands.c:180
#12 0x0000003105846124 in g_child_watch_dispatch ()
from /lib64/libglib-2.0.so.0
#13 0x00000031058492a6 in g_main_context_dispatch ()
from /lib64/libglib-2.0.so.0
#14 0x0000003105849628 in g_main_context_iterate.isra.24 ()
from /lib64/libglib-2.0.so.0
#15 0x0000003105849a3a in g_main_loop_run ()
from /lib64/libglib-2.0.so.0
#16 0x0000003b875aa355 in gtk_main () from /lib64/libgtk-3.so.0
#17 0x00000000004213e6 in main (argc=1, argv=0x7fffffffe0f8) at
bluefish.c:517


Regards,
Jim H
Olivier Sessink
2014-03-03 20:45:10 UTC
Permalink
Post by Jim Hayward
Hi Olivier,
A segfault occurs if an external command doesn't exist. This appears to
possibly only happen if there is a statuscode_cb. child_watch_lcb()
correctly sees the issue, but doesn't prevent start_command_idle() from
being run. A simple solution with the existing code appears to be just
if status !=0 g_source_remove(ep->start_command_idle_id).
I wonder if line 182 is the problem.

perhaps we should always check if ep->start_command_idle_id is set, and
if so cancel it.

right now we only cancel it if there is a pipe in and not a buffer out.
Why not always cancel? I can't think why this code was written as it is...

Olivier
--
Bluefish website http://bluefish.openoffice.nl/
Blog http://oli4444.wordpress.com/
Olivier Sessink
2014-03-03 21:55:36 UTC
Permalink
Post by Jim Hayward
Hi Olivier,
A segfault occurs if an external command doesn't exist. This appears to
possibly only happen if there is a statuscode_cb. child_watch_lcb()
correctly sees the issue, but doesn't prevent start_command_idle() from
being run. A simple solution with the existing code appears to be just
if status !=0 g_source_remove(ep->start_command_idle_id).
command_backend, started
create_commandstring, formatstring ' csstidy --preserve_css=true - '
seems OK
create_commandstring,is_local_non_modified=1, uri=0x885740, modified=0
create_commandstring, returning csstidy --preserve_css=true -
start_command_backend,commandstring= csstidy --preserve_css=true -
start_command_backend, pipe_in=1, pipe_out=1, include_stderr=0
start_command_backend, about to spawn process /bin/sh -c csstidy
--preserve_css=true -
Detaching after fork from child process 9489.
/bin/sh: csstidy: command not found
child_watch_lcb, child exited with status=32512
I don't understand this log: child_watch_lcb should now cancel the idle
callback event for start_command_idle
Post by Jim Hayward
filter_statuscode_lcb, exitcode 32512
start_command_idle, creating channel_in from pipe
but here start_command_idle is running?

any idea why this is happening?

Olivier
Post by Jim Hayward
--
Bluefish website http://bluefish.openoffice.nl/
Blog http://oli4444.wordpress.com/
Jim Hayward
2014-03-04 03:16:11 UTC
Permalink
Post by Olivier Sessink
Post by Jim Hayward
/bin/sh: csstidy: command not found
child_watch_lcb, child exited with status=32512
I don't understand this log: child_watch_lcb should now cancel the idle
callback event for start_command_idle
child_watch_lcb never has a chance to cancel start_command_idle.
Post by Olivier Sessink
Post by Jim Hayward
filter_statuscode_lcb, exitcode 32512
The segfault occurs in a separate process before filter_status_lcb
returns.
Post by Olivier Sessink
Post by Jim Hayward
start_command_idle, creating channel_in from pipe
but here start_command_idle is running?
any idea why this is happening?
This is what I see...

g_spawn_async_with_pipes() is called at 290. I think this doesn't return
false and set error because the process is created successfully. From
the docs it would think the command is argv[0] = /bin/sh. It wouldn't
help in this case but shouldn't if (error) at 296 be called prior to
calling g_child_watch_add()?

Look at the bt below. child_watch_lcb is run which calls
filter_statuscode_lcb. filter_statuscode_lcb creates a message dialog
and calls gtk_dialog_run. Now what appears to happen is while the main
loop is idle waiting for gtk_dialog_run to return, it executes
start_command_idle causing the segfault. If I check status !=0 and call
g_source remove before ep->statuscode_cb is called at 180, the segfault
doesn't happen.

#4 0x00000000004528ff in start_command_write_lcb (channel=0x8d36d0,
condition=<optimized out>, data=0x15ac270) at external_commands.c:143
#5 0x00000031058492a6 in g_main_context_dispatch ()
from /lib64/libglib-2.0.so.0
#6 0x0000003105849628 in g_main_context_iterate.isra.24 ()
from /lib64/libglib-2.0.so.0
#7 0x0000003105849a3a in g_main_loop_run ()
from /lib64/libglib-2.0.so.0
#8 0x0000003b87537620 in gtk_dialog_run () from /lib64/libgtk-3.so.0
#9 0x00000000004467f6 in message_dialog_new (parent=0x8fa2e0,
type=<optimized out>, button=GTK_BUTTONS_CLOSE, primaryText=0x4861c4
"Command returned error code",
secondaryText=0x13a3a00 "The command csstidy --preserve_css=true -
exited with error code 32512. Probably this application is not installed
on your system.") at dialog_utils.c:698
#10 0x0000000000452eab in filter_statuscode_lcb (status=<optimized out>,
bfwin=<optimized out>, data=0x15ac270) at external_commands.c:746
#11 0x000000000045299a in child_watch_lcb (pid=9489, status=32512,
data=0x15ac270) at external_commands.c:180


Regards,
Jim H
Olivier Sessink
2014-03-06 09:41:10 UTC
Permalink
Now I understand the problem:

filter_statuscode_lcb() calls message_dialog_new() which calls
gtk_dialog_run() which starts a new mainloop. In this mainloop
start_command_idle() is started before it is removed from the event loop!

So we have multiple options to fix this in a nice way:

1) remove start_command_idle() from the event loop before calling
filter_statuscode_lcb()

2a) don't use message_dialog_new() but just call
gtk_message_dialog_new() without starting a new mainloop.

2b) see if we can remove the call to gtk_dialog_run() from
message_dialog_new()

I prefer to do both 1 and 2: that might fix future problems as well.

Olivier
Post by Jim Hayward
Post by Olivier Sessink
Post by Jim Hayward
/bin/sh: csstidy: command not found
child_watch_lcb, child exited with status=32512
I don't understand this log: child_watch_lcb should now cancel the idle
callback event for start_command_idle
child_watch_lcb never has a chance to cancel start_command_idle.
Post by Olivier Sessink
Post by Jim Hayward
filter_statuscode_lcb, exitcode 32512
The segfault occurs in a separate process before filter_status_lcb
returns.
Post by Olivier Sessink
Post by Jim Hayward
start_command_idle, creating channel_in from pipe
but here start_command_idle is running?
any idea why this is happening?
This is what I see...
g_spawn_async_with_pipes() is called at 290. I think this doesn't return
false and set error because the process is created successfully. From
the docs it would think the command is argv[0] = /bin/sh. It wouldn't
help in this case but shouldn't if (error) at 296 be called prior to
calling g_child_watch_add()?
Look at the bt below. child_watch_lcb is run which calls
filter_statuscode_lcb. filter_statuscode_lcb creates a message dialog
and calls gtk_dialog_run. Now what appears to happen is while the main
loop is idle waiting for gtk_dialog_run to return, it executes
start_command_idle causing the segfault. If I check status !=0 and call
g_source remove before ep->statuscode_cb is called at 180, the segfault
doesn't happen.
#4 0x00000000004528ff in start_command_write_lcb (channel=0x8d36d0,
condition=<optimized out>, data=0x15ac270) at external_commands.c:143
#5 0x00000031058492a6 in g_main_context_dispatch ()
from /lib64/libglib-2.0.so.0
#6 0x0000003105849628 in g_main_context_iterate.isra.24 ()
from /lib64/libglib-2.0.so.0
#7 0x0000003105849a3a in g_main_loop_run ()
from /lib64/libglib-2.0.so.0
#8 0x0000003b87537620 in gtk_dialog_run () from /lib64/libgtk-3.so.0
#9 0x00000000004467f6 in message_dialog_new (parent=0x8fa2e0,
type=<optimized out>, button=GTK_BUTTONS_CLOSE, primaryText=0x4861c4
"Command returned error code",
secondaryText=0x13a3a00 "The command csstidy --preserve_css=true -
exited with error code 32512. Probably this application is not installed
on your system.") at dialog_utils.c:698
#10 0x0000000000452eab in filter_statuscode_lcb (status=<optimized out>,
bfwin=<optimized out>, data=0x15ac270) at external_commands.c:746
#11 0x000000000045299a in child_watch_lcb (pid=9489, status=32512,
data=0x15ac270) at external_commands.c:180
Regards,
Jim H
--
Bluefish website http://bluefish.openoffice.nl/
Blog http://oli4444.wordpress.com/
Continue reading on narkive:
Loading...