[patch 1/2] Fix watchpoints across fork

Pedro Alves alves.ped@gmail.com
Mon Jan 2 19:04:00 GMT 2012


On 01/02/2012 04:45 PM, Jan Kratochvil wrote:

> There is an issue that formerly linux-nat.c arch backends had ptid_t as their
> LWP parameter.  It has been changed by Pedro to `struct lwp_info *' recently
> but there does not exist any struct lwp_info for the LWPs being detached.  The
> patch creates struct lwp_info temporarily for the detach while keeping the
> current inferior intact (that lwp_info has then PID non-matching current
> inferior).
>
> I do not think it is related to the gdbserver protocol in any way, with
> "set detach-on-fork on" the "set follow-fork-mode" setting is solely target
> specific.

At some point, the remote protocol will need to learn about
following forks and maybe the follow-fork modes, but we don't have
to worry about it for this patch.

> -/* Callback for iterate_over_lwps.  Update the debug registers of
> -   LWP.  */
> +/* Callback for linux_nat_iterate_watchpoint_lwps.  Update the debug registers
> +   of LWP.  */
>
>   static int
>   update_debug_registers_callback (struct lwp_info *lwp, void *arg)
> @@ -364,9 +364,7 @@ update_debug_registers_callback (struct lwp_info *lwp, void *arg)
>   static void
>   amd64_linux_dr_set_control (unsigned long control)
>   {
> -  ptid_t pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
> -
> -  iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL);
> +  linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL);

This already iterated over threads of the current inferior only.
linux_nat_iterate_watchpoint_lwps does not do that, but leaves it to the
next patch instead.  It'd be better to move that hunk into this patch
already.

>   }
>
>   /* Set address REGNUM (zero based) to ADDR in all LWPs of the current
> @@ -379,7 +377,7 @@ amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
>
>     gdb_assert (regnum>= 0&&  regnum<= DR_LASTADDR - DR_FIRSTADDR);
>
> -  iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL);
> +  linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL);

I guess this leaves a stale `pid_ptid' local behind.


>   	}
>         else
>   	{
> @@ -671,6 +720,9 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
>   	  save_current_program_space ();
>
>   	  inferior_ptid = ptid_build (child_pid, child_pid, 0);
> +	  reinit_frame_cache ();
> +	  registers_changed ();

Only registers_changed is necessary.  That always invalidates the
frame cache of inferior_ptid.

> +
>   	  add_thread (inferior_ptid);
>   	  child_lp = add_lwp (inferior_ptid);
>   	  child_lp->stopped = 1;
> @@ -862,6 +914,9 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
>   	 informing the solib layer about this new process.  */
>
>         inferior_ptid = ptid_build (child_pid, child_pid, 0);
> +      reinit_frame_cache ();
> +      registers_changed ();

Likewise.

But, I'm not sure I understand why are these calls are necessary.  We
keep a  register cache list, indexed by ptid nowadays.  Could this
be a latent bug elsewhere?

> +
>         add_thread (inferior_ptid);
>         child_lp = add_lwp (inferior_ptid);
>         child_lp->stopped = 1;
> @@ -1112,21 +1167,6 @@ purge_lwp_list (int pid)
>       }
>   }


> +test parent FOLLOW_PARENT
> +
> +# Only GNU/Linux is known to support `set follow-fork-mode child'.

A [target_info exists gdb,no_hardware_watchpoints] check appears
missing, either to skip to test, or call "set can-use-hw-watchpoints
0".  Similarly, [skip_hw_breakpoint_tests] for the hardware breakpoints
bits.

Otherwise looks okay.

Took me a bit to convince myself i386_inferior_data_get was okay.
I wish it was cleaner (could be if we had a separate struct 
process_info, which will end up with, if/when we merge
gdb+gdbserver), but this will do for now.

-- 
Pedro Alves



More information about the Gdb-patches mailing list