Re: [obv] s390*: Fix build regression, remains execution regression

Pedro Alves
2011-12-17T12:29:59Z

On Saturday 17 December 2011 09:47:53, Jan Kratochvil wrote:
> Hi Pedro,
>
> this is the obvious part, checked in.
>
> Unfortunately there is still a regression, it crashes during exec from the
> wrapper->real inferior on mostly any program (kernel-2.6.32-220.el6.s390x):
>
> 61562 pts/1 T \_ /root/jkratoch/redhat/archer-git/gdb/gdb -nx -x ./transcript.1
> 61568 pts/1 T \_ /bin/bash -c exec /root/jkratoch/redhat/archer-git/gdb/testsuite/gdb.base/watchpoint-cond-gone
>
> (gdb) run
> Starting program: /root/jkratoch/redhat/archer-git/gdb/testsuite/gdb.base/watchpoint-cond-gone
> Couldn't retrieve watchpoint status: No such process.
> Couldn't get registers: No such process.

I suspect it's exposed by this change:

2011-12-14 Pedro Alves <pedro@codesourcery.com>

PR threads/10729

* linux-nat.c:
...
(add_lwp): Call linux_nat_new_thread even on the first LWP.
...

That code used to look like:

if (num_lwps (GET_PID (ptid)) > 1 && linux_nat_new_thread != NULL)
linux_nat_new_thread (ptid);

s390_fix_watch_points is the new_thread callback:

linux_nat_set_new_thread (t, s390_fix_watch_points);

> static void
> s390_fix_watch_points (struct lwp_info *lp)
> {
> int tid;
>
> per_struct per_info;
> ptrace_area parea;
>
> CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0;
> struct watch_area *area;
>
> tid = TIDGET (lp->ptid);
> if (tid == 0)
> tid = PIDGET (lp->ptid);
>
> for (area = watch_base; area; area = area->next)
> {
> watch_lo_addr = min (watch_lo_addr, area->lo_addr);
> watch_hi_addr = max (watch_hi_addr, area->hi_addr);
> }
>
> parea.len = sizeof (per_info);
> parea.process_addr = (addr_t) & per_info;
> parea.kernel_addr = offsetof (struct user_regs_struct, per_info);
> if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea) < 0)
> perror_with_name (_("Couldn't retrieve watchpoint status"));
>
> if (watch_base)
> {
> per_info.control_regs.bits.em_storage_alteration = 1;
> per_info.control_regs.bits.storage_alt_space_ctl = 1;
> }
> else
> {
> per_info.control_regs.bits.em_storage_alteration = 0;
> per_info.control_regs.bits.storage_alt_space_ctl = 0;
> }
> per_info.starting_addr = watch_lo_addr;
> per_info.ending_addr = watch_hi_addr;
>
> if (ptrace (PTRACE_POKEUSR_AREA, tid, &parea) < 0)
> perror_with_name (_("Couldn't modify watchpoint status"));
> }

Looks like we're trying to peek/poke at the shell process,
and failing?

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);
+}

- linux_nat_set_new_thread (t, s390_fix_watch_points);
+ linux_nat_set_new_thread (t, s390_new_thread);

Would fix it.

--
Pedro Alves