Re: [PATCH 8/8] gdb: resume ongoing step after handling fork or vfork

Pedro Alves
2022-03-31T18:24:18Z

On 2022-01-17 16:27, Simon Marchi via Gdb-patches wrote:
> From: Simon Marchi <simon.marchi@efficios.com>
>
> The test introduced by this patch would fail in this configuration, with
> the native-gdbserver or native-extended-gdbserver boards:
>
> FAIL: gdb.threads/next-fork-other-thread.exp: fork_func=fork: target-non-stop=auto: non-stop=off: displaced-stepping=auto: i=2: next to for loop
>
> The problem is that the step operation is forgotten when handling the
> fork/vfork. With "debug infrun" and "debug remote", it looks like this
> (some lines omitted for brevity). We do the next:
>
> [infrun] proceed: enter
> [infrun] proceed: addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT
> [infrun] resume_1: step=1, signal=GDB_SIGNAL_0, trap_expected=0, current thread [4154304.4154304.0] at 0x5555555553bf
> [infrun] do_target_resume: resume_ptid=4154304.0.0, step=1, sig=GDB_SIGNAL_0
> [remote] Sending packet: $vCont;r5555555553bf,5555555553c4:p3f63c0.3f63c0;c:p3f63c0.-1#cd
> [infrun] proceed: exit
>
> We then handle a fork event:
>
> [infrun] fetch_inferior_event: enter
> [remote] wait: enter
> [remote] Packet received: T05fork:p3f63ee.3f63ee;06:0100000000000000;07:b08e59f6ff7f0000;10:bf60e8f7ff7f0000;thread:p3f63c0.3f63c6;core:17;
> [remote] wait: exit
> [infrun] print_target_wait_results: target_wait (-1.0.0 [process -1], status) =
> [infrun] print_target_wait_results: 4154304.4154310.0 [Thread 4154304.4154310],
> [infrun] print_target_wait_results: status->kind = FORKED, child_ptid = 4154350.4154350.0
> [infrun] handle_inferior_event: status->kind = FORKED, child_ptid = 4154350.4154350.0
> [remote] Sending packet: $D;3f63ee#4b
> [infrun] resume_1: step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [4154304.4154310.0] at 0x7ffff7e860bf
> [infrun] do_target_resume: resume_ptid=4154304.0.0, step=0, sig=GDB_SIGNAL_0
> [remote] Sending packet: $vCont;c:p3f63c0.-1#73
> [infrun] fetch_inferior_event: exit
>
> In the first snippet, we resume the stepping thread with the range-stepping (r)
> vCont command. But after handling the fork (detaching the fork child), we
> resumed the whole process freely. The stepping thread, which was paused by
> GDBserver while reporting the fork event, was therefore resumed freely, instead
> of confined to the addresses of the stepped line. Note that since this
> is a "next", it could be that we have entered a function, installed a
> step-resume breakpoint, and it's ok to continue freely the stepping
> thread, but that's not the case here. The two snippets shown above were
> next to each other in the logs.
>
> For the fork case, we can resume stepping right after handling the
> event.
>
> However, for the vfork case, where we are waiting for the
> external child process to exec or exit, we only resume the thread that
> called vfork, and keep the others stopped (see patch "gdb: fix handling of
> vfork by multi-threaded program" prior in this series). So we can't
> resume the stepping thread right now. Instead, do it after handling the
> vfork-done event.

Also OK.

Thanks for doing all this.