From f489207efde922e436b1b420d4de071927e3b9d5 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Thu, 28 Mar 2019 09:29:22 -0700 Subject: 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 * 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 * gdb.threads/watchpoint-fork.exp (test): Use large timeout factor when no hardware watchpoint support. --- gdb/nios2-tdep.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gdb/nios2-tdep.h') diff --git a/gdb/nios2-tdep.h b/gdb/nios2-tdep.h index a2f0163..275dcd7 100644 --- a/gdb/nios2-tdep.h +++ b/gdb/nios2-tdep.h @@ -74,6 +74,9 @@ struct gdbarch_tdep CORE_ADDR (*syscall_next_pc) (struct frame_info *frame, const struct nios2_opcode *op); + /* Returns true if PC points to a kernel helper function. */ + bool (*is_kernel_helper) (CORE_ADDR pc); + /* Offset to PC value in jump buffer. If this is negative, longjmp support will be disabled. */ int jb_pc; -- cgit v1.1