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

Pedro Alves pedro@codesourcery.com
Sat Dec 17 12:33:00 GMT 2011


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



More information about the Gdb-patches mailing list