Fix stepping past unwritable kernel helper on nios2-linux-gnu.
authorSandra Loosemore <sandra@codesourcery.com>
Thu, 28 Mar 2019 16:29:22 +0000 (09:29 -0700)
committerSandra Loosemore <sandra@codesourcery.com>
Thu, 28 Mar 2019 16:29:22 +0000 (09:29 -0700)
commitf489207efde922e436b1b420d4de071927e3b9d5
treed2c155fb7a9b7f4fec5fc0af7d18bbae11ee0d57
parentc92df149c29518f6e1d4a3174b3e29162fcd3ad6
Fix stepping past unwritable kernel helper on nios2-linux-gnu.

This patch fixes a problem on nios2-linux-gnu with stepping past the
kernel helper __kuser_cmpxchg, which was exposed by the testcase
gdb.threads/watchpoint-fork.exp.  The kernel maps this function into
user space on an unwritable page.  In this testcase, the cmpxchg
helper is invoked indirectly from the setbuf call in the test program.
Since this target lacks hardware breakpoint/watchpoint support, GDB
tries to single-step through the program by setting software
breakpoints, and was just giving an error when it reached the function
on the unwritable page.

The solution here is to always step over the call instead of stepping
into it; cmpxchg is supposed to be an atomic operation so this
behavior seems reasonable.  The hook in nios2_get_next_pc is somewhat
generic, but at present cmpxchg is the only helper provided by the
Linux kernel that is invoked by an ordinary function call.  (Signal
return trampolines also go through the unwritable page but not by a
function call.)

Fixing this issue also revealed that the testcase needs a much larger
timeout factor when software single-stepping is used.  That has also
been fixed in this patch.

gdb/ChangeLog

2019-03-28  Sandra Loosemore  <sandra@codesourcery.com>

        * nios2-tdep.h (struct gdbarch_tdep): Add is_kernel_helper.
        * nios2-tdep.c (nios2_get_next_pc): Skip over kernel helpers.
        * nios2-linux-tdep.c (nios2_linux_is_kernel_helper): New.
        (nios2_linux_init_abi): Install it.

gdb/testsuite/ChangeLog

2019-03-28  Sandra Loosemore  <sandra@codesourcery.com>

        * gdb.threads/watchpoint-fork.exp (test): Use large timeout
        factor when no hardware watchpoint support.
gdb/ChangeLog
gdb/nios2-linux-tdep.c
gdb/nios2-tdep.c
gdb/nios2-tdep.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.threads/watchpoint-fork.exp