[patch] s390*: watchpoints regression [Re: [obv] s390*: Fix build regression]

Jan Kratochvil
2011-12-17T19:16:12Z

On Sat, 17 Dec 2011 13:29:27 +0100, Pedro Alves wrote:
> Looks like we're trying to peek/poke at the shell process,
> and failing?

Yes.

> I suspect that something like this pseudo patch:
>
> +s390_new_thread (struct lwp_info *lp)
> +{
> + if (num_lwps (GET_PID (ptid)) > 1)
> + s390_fix_watch_points (lp);
> +}

I can confirm it works.

On x86* it now sets DR_CONTROL to 0 already for the wrapper shell. When there
exist watchpoints they are suppressed so it still sets 0 and it works. But
I do not think GDB should mess with watchpoint registers already for the
wrapper shell.

In the hypothetical case the wrapper shell sets DR registers they get
inherited now by the inferior. Not that it needs to be handled but it IMO
suggests DR_CONTROL should be rather set for the real inferior.

But I do not see some easy enough way how to delay the DR setting till the new
inferior so I just verified your code which works.

OK to check it in this way?

Thanks,
Jan

2011-12-17 Pedro Alves <pedro@codesourcery.com>
Jan Kratochvil <jan.kratochvil@redhat.com>

* s390-nat.c (s390_new_thread_lwp, s390_new_thread): New functions.
(_initialize_s390_nat): Install now s390_new_thread, not
s390_fix_watch_points.

--- a/gdb/s390-nat.c
+++ b/gdb/s390-nat.c
@@ -667,6 +667,38 @@ s390_read_description (struct target_ops *ops)
tdesc_s390_linux32);
}

+/* Helper for s390_new_thread. */
+
+static int
+s390_new_thread_lwp (struct lwp_info *lp, void *new_lp_voidp)
+{
+ struct lwp_info *new_lp = new_lp_voidp;
+
+ if (lp == new_lp)
+ {
+ /* Continue traversal. */
+ return 0;
+ }
+
+ s390_fix_watch_points (new_lp);
+
+ /* Stop traversal. */
+ return 1;
+}
+
+/* Execute s390_fix_watch_points only when there is at least one other LWP
+ besides the new one. This excludes the initial shell wrapper process which
+ works around a problem of s390x failing to PTRACE_POKEUSR_AREA when the
+ initial shell wrapper runs. s390_fix_watch_points is fortunately not needed
+ for the initial creation of a single threaded process - watchpoints are not
+ yet inserted into inferior in such case. */
+
+static void
+s390_new_thread (struct lwp_info *lp)
+{
+ iterate_over_lwps (pid_to_ptid (GET_PID (lp->ptid)), s390_new_thread_lwp, lp);
+}
+
void _initialize_s390_nat (void);

void
@@ -695,5 +727,5 @@ _initialize_s390_nat (void)

/* Register the target. */
linux_nat_add_target (t);
- linux_nat_set_new_thread (t, s390_fix_watch_points);
+ linux_nat_set_new_thread (t, s390_new_thread);
}