Discussion:
[Bug breakpoints/23845] New: Watchpoints (and watchpoint tests) are failing
pmuldoon at redhat dot com
2018-10-31 08:11:28 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=23845

Bug ID: 23845
Summary: Watchpoints (and watchpoint tests) are failing
Product: gdb
Version: HEAD
Status: NEW
Severity: critical
Priority: P2
Component: breakpoints
Assignee: unassigned at sourceware dot org
Reporter: pmuldoon at redhat dot com
Target Milestone: ---

To replicate simply run the gdb.base/watchpoint.exp test.

Some analysis:

Breakpoint 5, func2 () at
/home/pmuldoon/fedora_gdb_patches/upstream/obj/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c:100

100 ival5++;

(gdb) PASS: gdb.base/watchpoint.exp: continue to breakpoint: func2 breakpoint
here, first time
watch local_a

Hardware watchpoint 6: local_a

(gdb) PASS: gdb.base/watchpoint.exp: set local watch
cont

Continuing.

Couldn't write debug register: Invalid argument.

Later, and more seriously, the inferior dies (it shouldn't)

Watchpoint 6 deleted because the program has left the block

in which its expression is valid.

Program received signal SIGSEGV, Segmentation fault.

0x000000000040059b in func2 () at
/home/pmuldoon/fedora_gdb_patches/upstream/obj/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c:100

100 ival5++;

If you attempt to replicate the test manually, it won't trigger:


***@UNKNOWN ~/fedora_gdb_patches/upstream/obj/gdb/testsuite ] ../gdb
outputs/gdb.base/watchpoint/watchpoint
GNU gdb (GDB) 8.2.50.20181031-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from outputs/gdb.base/watchpoint/watchpoint...

(gdb) b marker6
Breakpoint 1 at 0x400556: file
/home/pmuldoon/fedora_gdb_patches/upstream/obj/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c,
line 82.
(gdb) r
Starting program:
/home/pmuldoon/fedora_gdb_patches/upstream/obj/gdb/testsuite/outputs/gdb.base/watchpoint/watchpoint

marker6 () at
/home/pmuldoon/fedora_gdb_patches/upstream/obj/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c:82
82 }
(gdb) b 99
Breakpoint 2 at 0x400592: file
/home/pmuldoon/fedora_gdb_patches/upstream/obj/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c,
line 100.

(gdb) c
Continuing.

Breakpoint 2
func2 () at
/home/pmuldoon/fedora_gdb_patches/upstream/obj/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c:100
100 ival5++;

(gdb) watch local_a
Hardware watchpoint 3: local_a

(gdb) c
Continuing.

Hardware watchpoint 3: local_a

Old value = 0
New value = 1
func2 () at
/home/pmuldoon/fedora_gdb_patches/upstream/obj/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c:102
102 static_b = local_a;
(gdb) bt
#0 func2 () at
/home/pmuldoon/fedora_gdb_patches/upstream/obj/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c:102
#1 0x000000000040082f in main () at
/home/pmuldoon/fedora_gdb_patches/upstream/obj/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base/watchpoint.c:234

(gdb) list 100
95 {
96 int local_a = 0;
97 static int static_b;
98
99 /* func2 breakpoint here */
100 ival5++;
101 local_a = ival5;
102 static_b = local_a;
103 }
104


I am trying to replicate a simpler fail case. Simply replicating the conditions
in the func2() function won't work. I suspect the tests run before, in
test_simple_watchpoint, in watchpoint.exp are priming the conditions for the
failure.
--
You are receiving this mail because:
You are on the CC list for the bug.
pmuldoon at redhat dot com
2018-10-31 08:34:13 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=23845

--- Comment #1 from Phil Muldoon <pmuldoon at redhat dot com> ---
The actual failure occurs here in nat/x86-linux-dregs.c:68 on the system call:

ptrace (PTRACE_POKEUSER, tid, u_debugreg_offset (regnum), value);
if (errno != 0)
perror_with_name (_("Couldn't write debug register"));

The actual call is somewhere else, I believe, either with the values of the
arguments or some changed accounting in the kernel.
--
You are receiving this mail because:
You are on the CC list for the bug.
pmuldoon at redhat dot com
2018-10-31 16:42:22 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=23845

--- Comment #2 from Phil Muldoon <pmuldoon at redhat dot com> ---
Ok, the watchpoints work on (a not updated) Fedora 27 and fail on Fedora 28. I
fetched the diff from the 4.13.9 kernel and the 4.18.16 kernels (unpatched
upstream kernels). The diff of arch/x86/kernel/ptrace.c is

diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index f37d18124648..e2ee403865eb 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -935,7 +935,7 @@ static int putreg32(struct task_struct *child, unsigned
regno, u32 value)
*/
regs->orig_ax = value;
if (syscall_get_nr(child, regs) >= 0)
- child->thread.status |= TS_I386_REGS_POKED;
+ child->thread_info.status |= TS_I386_REGS_POKED;
break;

case offsetof(struct user32, regs.eflags):
@@ -1377,7 +1377,6 @@ static void fill_sigtrap_info(struct task_struct *tsk,
tsk->thread.trap_nr = X86_TRAP_DB;
tsk->thread.error_code = error_code;

- memset(info, 0, sizeof(*info));
info->si_signo = SIGTRAP;
info->si_code = si_code;
info->si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
@@ -1395,6 +1394,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs
*regs,
{
struct siginfo info;

+ clear_siginfo(&info);
fill_sigtrap_info(tsk, regs, error_code, si_code, &info);
/* Send us the fake SIGTRAP */
force_sig_info(SIGTRAP, &info, tsk);
--
You are receiving this mail because:
You are on the CC list for the bug.
Loading...