diff options
author | Pedro Alves <pedro@palves.net> | 2024-06-21 15:14:08 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2024-06-21 15:14:08 +0200 |
commit | 50de502a4f843310e231b3174804e95a9e7de4fc (patch) | |
tree | 449ddc510ef5a757d1b88f1769a3c07cd370fab7 /gdb/arm-linux-nat.c | |
parent | f4a966a91d23ae78000d577665502edff7274fd9 (diff) | |
download | binutils-50de502a4f843310e231b3174804e95a9e7de4fc.zip binutils-50de502a4f843310e231b3174804e95a9e7de4fc.tar.gz binutils-50de502a4f843310e231b3174804e95a9e7de4fc.tar.bz2 |
[gdb/tdep] Fix gdb.base/watchpoint-running.exp on {arm,ppc64le}-linux
When running test-case gdb.base/watchpoint-running on ppc64le-linux (and
similar on arm-linux), we get:
...
(gdb) watch global_var^M
warning: Error when detecting the debug register interface. \
Debug registers will be unavailable.^M
Watchpoint 2: global_var^M
(gdb) FAIL: $exp: all-stop: hardware: watch global_var
FAIL: $exp: all-stop: hardware: watchpoint hit (timeout)
...
The problem is that ppc_linux_dreg_interface::detect fails to detect the
hardware watchpoint interface, because the calls to ptrace return with errno
set to ESRCH.
This is a feature of ptrace: if a call is done while the tracee is not
ptrace-stopped, it returns ESRCH.
Indeed, in the test-case "watch global_var" is executed while the inferior is
running, and that triggers the first call to ppc_linux_dreg_interface::detect.
And because the detection failure is cached, subsequent attempts at setting
hardware watchpoints will also fail, even if the tracee is ptrace-stopped.
The way to fix this is to make sure that ppc_linux_dreg_interface::detect is
called when we know that the thread is ptrace-stopped, which in the current
setup is best addressed by using target-specific post_attach and
post_startup_inferior overrides. However, as we can see in
aarch64_linux_nat_target, that causes code duplication.
Fix this by:
- defining a new target hook low_init_process, called from
linux_init_ptrace_procfs, which is called from both
linux_nat_target::post_attach and linux_nat_target::post_startup_inferior,
- adding implementations for ppc_linux_nat_target and arm_linux_nat_target
that detect the hardware watchpoint interface,
- replacing the aarch64_linux_nat_target implementations of post_attach and
post_startup_inferior with a low_init_process implementation.
Tested on ppc64le-linux, arm-linux, aarch64-linux and x86_64-linux.
Co-Authored-By: Tom de Vries <tdevries@suse.de>
Approved-By: Luis Machado <luis.machado@arm.com>
PR tdep/31834
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31834
PR tdep/31705
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31705
Diffstat (limited to 'gdb/arm-linux-nat.c')
-rw-r--r-- | gdb/arm-linux-nat.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c index 50c24ec..ac53bed 100644 --- a/gdb/arm-linux-nat.c +++ b/gdb/arm-linux-nat.c @@ -103,6 +103,7 @@ public: /* Handle process creation and exit. */ void low_new_fork (struct lwp_info *parent, pid_t child_pid) override; + void low_init_process (pid_t pid) override; void low_forget_process (pid_t pid) override; }; @@ -805,6 +806,19 @@ arm_linux_process_info_get (pid_t pid) return proc; } +/* Implement the "low_init_process" target_ops method. */ + +void +arm_linux_nat_target::low_init_process (pid_t pid) +{ + /* Set the hardware debug register capacity. This requires the process to be + ptrace-stopped, otherwise detection will fail and software watchpoints will + be used instead of hardware. If we allow this to be done lazily, we + cannot guarantee that it's called when the process is ptrace-stopped, so + do it now. */ + arm_linux_get_hwbp_cap (); +} + /* Called whenever GDB is no longer debugging process PID. It deletes data structures that keep track of debug register state. */ |