* Refuse following the vfork parent if not letting the child run.
@ 2009-06-08 13:30 Pedro Alves
2009-06-08 14:31 ` Daniel Jacobowitz
0 siblings, 1 reply; 6+ messages in thread
From: Pedro Alves @ 2009-06-08 13:30 UTC (permalink / raw)
To: gdb-patches
If you try to follow a vfork parent, without letting the
child run, GDB hangs. E.g., gdb 6.8 or head:
>gdb-6.8 ./testsuite/gdb.base/foll-vfork
:
(gdb) set detach-on-fork off
(gdb) start
Breakpoint 1 at 0x4005c0: file ../../../src/gdb/testsuite/gdb.base/foll-vfork.c, line 12.
Starting program: /home/pedro/gdb/sspaces/build/gdb/testsuite/gdb.base/foll-vfork
main () at ../../../src/gdb/testsuite/gdb.base/foll-vfork.c:12
12 pid = vfork ();
(gdb) c
Continuing.
<HANG>
No amount of ctrl-c will let you out of this. Only going to another
terminal and killing gdb bails you out.
I've been keeping the patch below locally to prevent
getting myself in such situation. (GNU make uses vfork, and much of
my multi-process testing involves running make. How convenient :-) )
The manual already mentions that you can't debug the vfork parent
until the child execs in the forks section.
Comments? (This applies on top the the patch that adds the
option to resume all threads of all processes.)
A patched GDB shows this:
(gdb) set detach-on-fork off
(gdb) start
Temporary breakpoint 1 at 0x4005c0: file ../../../src/gdb/testsuite/gdb.base/foll-vfork.c, line 12.
Starting program: /home/pedro/gdb/sspaces/build/gdb/testsuite/gdb.base/foll-vfork
Temporary breakpoint 1, main () at ../../../src/gdb/testsuite/gdb.base/foll-vfork.c:12
12 pid = vfork ();
(gdb) n
warning: Can not debug the parent of a vfork in the foreground if not letting
the child run until it execs or exits, as it would deadlock the terminal.
0x00007ffff789aee4 in vfork () from /lib/libc.so.6
(gdb)
--
Pedro Alves
2009-06-08 Pedro Alves <pedro@codesourcery.com>
* linux-nat.c (linux_child_follow_fork): Refuse to follow a vfork
parent in the foreground if not letting the child run.
---
gdb/linux-nat.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c 2009-06-08 13:22:47.000000000 +0100
+++ src/gdb/linux-nat.c 2009-06-08 14:27:05.000000000 +0100
@@ -596,6 +596,21 @@ linux_child_follow_fork (struct target_o
if (!detach_fork)
linux_enable_event_reporting (pid_to_ptid (child_pid));
+ if (has_vforked
+ && (!target_is_async_p () || sync_execution)
+ && !(follow_child || detach_fork || sched_multi))
+ {
+ /* The parent stays blocked inside the vfork syscall until the
+ child execs or exits. If we don't let the child run, then
+ the parent stays blocked. If we're telling the parent to run
+ in the foreground, the user will not be able to ctrl-c to get
+ back the terminal, effectively hanging the debug session. */
+ warning (_("\
+Can not debug the parent of a vfork in the foreground if not letting \
+the child run until it execs or exits, as it would deadlock the terminal."));
+ return 1;
+ }
+
if (! follow_child)
{
/* We're already attached to the parent, by default. */
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Refuse following the vfork parent if not letting the child run.
2009-06-08 13:30 Refuse following the vfork parent if not letting the child run Pedro Alves
@ 2009-06-08 14:31 ` Daniel Jacobowitz
2009-06-08 14:39 ` Pedro Alves
0 siblings, 1 reply; 6+ messages in thread
From: Daniel Jacobowitz @ 2009-06-08 14:31 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
On Mon, Jun 08, 2009 at 02:31:38PM +0100, Pedro Alves wrote:
> A patched GDB shows this:
>
> (gdb) set detach-on-fork off
> (gdb) start
> Temporary breakpoint 1 at 0x4005c0: file ../../../src/gdb/testsuite/gdb.base/foll-vfork.c, line 12.
> Starting program: /home/pedro/gdb/sspaces/build/gdb/testsuite/gdb.base/foll-vfork
>
> Temporary breakpoint 1, main () at ../../../src/gdb/testsuite/gdb.base/foll-vfork.c:12
> 12 pid = vfork ();
> (gdb) n
> warning: Can not debug the parent of a vfork in the foreground if not letting
> the child run until it execs or exits, as it would deadlock the terminal.
> 0x00007ffff789aee4 in vfork () from /lib/libc.so.6
> (gdb)
None of your explanation, the patch, or the example output tells me
what GDB is doing instead :-) IOW, I think a "warning" about the
situation here is strange; something has happened, and we don't say
what.
Is this actually a fork-following error, and we've stopped execution?
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Refuse following the vfork parent if not letting the child run.
2009-06-08 14:31 ` Daniel Jacobowitz
@ 2009-06-08 14:39 ` Pedro Alves
2009-06-08 15:03 ` Pedro Alves
0 siblings, 1 reply; 6+ messages in thread
From: Pedro Alves @ 2009-06-08 14:39 UTC (permalink / raw)
To: gdb-patches; +Cc: Daniel Jacobowitz
On Monday 08 June 2009 15:31:11, Daniel Jacobowitz wrote:
> On Mon, Jun 08, 2009 at 02:31:38PM +0100, Pedro Alves wrote:
> > A patched GDB shows this:
> >
> > (gdb) set detach-on-fork off
> > (gdb) start
> > Temporary breakpoint 1 at 0x4005c0: file ../../../src/gdb/testsuite/gdb.base/foll-vfork.c, line 12.
> > Starting program: /home/pedro/gdb/sspaces/build/gdb/testsuite/gdb.base/foll-vfork
> >
> > Temporary breakpoint 1, main () at ../../../src/gdb/testsuite/gdb.base/foll-vfork.c:12
> > 12 pid = vfork ();
> > (gdb) n
> > warning: Can not debug the parent of a vfork in the foreground if not letting
> > the child run until it execs or exits, as it would deadlock the terminal.
> > 0x00007ffff789aee4 in vfork () from /lib/libc.so.6
> > (gdb)
>
> None of your explanation, the patch, or the example output tells me
> what GDB is doing instead :-)
I suck at output messages and docs. It's sort of in the patch :-). Returning
1 from follow_fork makes the caller not carry on with resuming.
> IOW, I think a "warning" about the
> situation here is strange; something has happened, and we don't say
> what.
> Is this actually a fork-following error, and we've stopped execution?
I guess you could call it an error. We can't satisfy the users request,
so we kind of stopped execution --- in reality, we're refusing to
continue execution, as the inferior is stopped already.
--
Pedro Alves
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Refuse following the vfork parent if not letting the child run.
2009-06-08 14:39 ` Pedro Alves
@ 2009-06-08 15:03 ` Pedro Alves
2009-06-08 15:43 ` Daniel Jacobowitz
0 siblings, 1 reply; 6+ messages in thread
From: Pedro Alves @ 2009-06-08 15:03 UTC (permalink / raw)
To: gdb-patches; +Cc: Daniel Jacobowitz
On Monday 08 June 2009 15:40:23, Pedro Alves wrote:
> > Is this actually a fork-following error, and we've stopped execution?
>
> I guess you could call it an error. We can't satisfy the users request,
> so we kind of stopped execution --- in reality, we're refusing to
> continue execution, as the inferior is stopped already.
How about?
(gdb) n
error resuming execution: can not resume the parent of a vfork in the
foreground if not letting the child run until it execs or exits, as
it would lock the terminal and hang the debug session.
0x00007ffff789aee4 in vfork () from /lib/libc.so.6
(gdb)
--
Pedro Alves
2009-06-08 Pedro Alves <pedro@codesourcery.com>
* linux-nat.c (linux_child_follow_fork): Refuse to follow a vfork
parent in the foreground if not letting the child run.
---
gdb/linux-nat.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c 2009-06-08 13:22:47.000000000 +0100
+++ src/gdb/linux-nat.c 2009-06-08 16:01:40.000000000 +0100
@@ -596,6 +596,21 @@ linux_child_follow_fork (struct target_o
if (!detach_fork)
linux_enable_event_reporting (pid_to_ptid (child_pid));
+ if (has_vforked
+ && (!target_is_async_p () || sync_execution)
+ && !(follow_child || detach_fork || sched_multi))
+ {
+ /* The parent stays blocked inside the vfork syscall until the
+ child execs or exits. If we don't let the child run, then
+ the parent stays blocked. If we're telling the parent to run
+ in the foreground, the user will not be able to ctrl-c to get
+ back the terminal, effectively hanging the debug session. */
+ fprintf_filtered (gdb_stderr, _("\
+error resuming execution: can not resume the parent of a vfork in the foreground if not letting \
+the child run until it execs or exits, as it would lock the terminal and hang the debug session.\n"));
+ return 1;
+ }
+
if (! follow_child)
{
/* We're already attached to the parent, by default. */
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Refuse following the vfork parent if not letting the child run.
2009-06-08 15:03 ` Pedro Alves
@ 2009-06-08 15:43 ` Daniel Jacobowitz
2009-06-08 17:44 ` Pedro Alves
0 siblings, 1 reply; 6+ messages in thread
From: Daniel Jacobowitz @ 2009-06-08 15:43 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
On Mon, Jun 08, 2009 at 04:04:35PM +0100, Pedro Alves wrote:
> On Monday 08 June 2009 15:40:23, Pedro Alves wrote:
>
> > > Is this actually a fork-following error, and we've stopped execution?
> >
> > I guess you could call it an error. We can't satisfy the users request,
> > so we kind of stopped execution --- in reality, we're refusing to
> > continue execution, as the inferior is stopped already.
>
> How about?
>
> (gdb) n
> error resuming execution: can not resume the parent of a vfork in the
> foreground if not letting the child run until it execs or exits, as
> it would lock the terminal and hang the debug session.
> 0x00007ffff789aee4 in vfork () from /lib/libc.so.6
> (gdb)
From the user's point of view, we might have failed to resume, or we
might have stopped a running program. It's always helpful to offer a
suggestion. Something like:
(gdb) n
Can not resume the parent process over vfork while holding the child
stopped. Try "set SOMETHING" or "set SOMETHING ELSE".
Also, what about MI?
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Refuse following the vfork parent if not letting the child run.
2009-06-08 15:43 ` Daniel Jacobowitz
@ 2009-06-08 17:44 ` Pedro Alves
0 siblings, 0 replies; 6+ messages in thread
From: Pedro Alves @ 2009-06-08 17:44 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Monday 08 June 2009 16:43:28, Daniel Jacobowitz wrote:
> Also, what about MI?
Ah, the MI trick question. :-)
( The follow-fork-mode model is a bit etchy to begin with. It
would be simpler if targets supporting forks had to support
multiprocess as well, and we just added new the processes to the
list as we find them. Then the user just switches to the process
desired before resuming. But, there's plain gdbserver "target remote", and
we may end up with follow-fork support there. What do you think
of that? Anyway, this deadlock still needs to be prevented. )
If the parent is running free, and then vforks, we stop
the inferior. I'm not sure if this should be considered an
error at the MI level? As is, MI gets its *stop
notification. The *why* it stopped ends up being a bit
misterious, though. I imagine this being a current MI
limitation in other cases too.
(gdb)
set detach off
&"set detach off\n"
^done
(gdb)
-exec-continue
^running
*running,thread-id="all"
(gdb)
&"error resuming execution: can not resume the parent of a vfork in the foreground if not letting the child run until it execs or exits, as it would lock the terminal and hang the debug session.\n"
*stopped,frame={addr="0x00007ffff789aee4",func="vfork",args=[],from="/lib/libc.so.6"},thread-id="1",stopped-threads="all"
(gdb)
If I made that an error call instead I would get this:
-exec-run
=thread-exited,id="1",group-id="1828"
=thread-group-exited,id="1828"
=library-unloaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",host-name="/lib64/ld-linux-x86-64.so.2"
=library-unloaded,id="/lib/libm.so.6",target-name="/lib/libm.so.6",host-name="/lib/libm.so.6"
=library-unloaded,id="/lib/libc.so.6",target-name="/lib/libc.so.6",host-name="/lib/libc.so.6"
=thread-group-created,id="1886"
=thread-created,id="1",group-id="1886"
^running
*running,thread-id="all"
(gdb)
=library-loaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",host-name="/lib64/ld-linux-x86-64.so.2",symbols-loaded="0"
=library-loaded,id="/lib/libm.so.6",target-name="/lib/libm.so.6",host-name="/lib/libm.so.6",symbols-loaded="0"
=library-loaded,id="/lib/libc.so.6",target-name="/lib/libc.so.6",host-name="/lib/libc.so.6",symbols-loaded="0"
^error,msg="error resuming execution: can not resume the parent of a vfork in the foreground if not letting the child run until it execs or exits, as it would lock the terminal and hang the debug session.\n"
=thread-selected,id="1"
(gdb)
Meaning, we'd need to do something smarter with exceptions from
within target_follow_fork so to report a *stopped to the frontend
here as well. (This isn't so much an exceptional case though, in
the sense that it's unexpected --- the caller is prepared to
handle this "refuse to go" case.)
(insert rant about one of ^running or ^error looking out of
place -- take your pick)
So, I don't know what's best here. MI with multiforks is
basically undefined at this point.
--
Pedro Alves
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-06-08 17:44 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-08 13:30 Refuse following the vfork parent if not letting the child run Pedro Alves
2009-06-08 14:31 ` Daniel Jacobowitz
2009-06-08 14:39 ` Pedro Alves
2009-06-08 15:03 ` Pedro Alves
2009-06-08 15:43 ` Daniel Jacobowitz
2009-06-08 17:44 ` Pedro Alves
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox