Hardware breakpoints can only be set at module initialization
When a process issues a system call, it switches to kernel mode, but the kernel code is running in "process context". The process could, in theory, do anything while running in kernel mode. However, typical kernel code will check that the calling process has the capability to do what it is trying to do. A process has a list of capabilities of things it is allowed to do: see capabilities(7).
In OP's particular case, the unprivileged process that is issuing the ioctl
call that results in the call to register_wide_hw_breakpoint
is probably failing when it fails the check in the hw_breakpoint_parse
function in "kernel/events/hw_breakpoint.c":
if (arch_check_bp_in_kernelspace(hw)) {
if (attr->exclude_kernel)
return -EINVAL;
/*
* Don't let unprivileged users set a breakpoint in the trap
* path to avoid trap recursion attacks.
*/
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
}
arm64 - Hardware [break/watch]point: what happens if we set a hardware [break/watch]point and two applications have the same virtual address?
Can the breakpoint (watchpoint), supposed for process A, being triggered erroneously by the same virtual address reached by process B?
Yes.
At whatever point you switch out TTBRx_EL1, you should also switch out the break-/watchpoint registers.
Need an overview of debugging process from the hardware layer
The x86 ISA includes a single-byte int3
encoding that's intended for software breakpoints. GDB uses this (via ptrace) by default for breakpoints.
(Why Single Stepping Instruction on X86?)
x86 also has a Trap Flag (TF) in EFLAGS for single-step mode. (https://en.wikipedia.org/wiki/Trap_flag). See also Difference between trap flag (TF) and monitor trap flag?
There are even "debug registers" for setting hardware breakpoints, without modifying the machine code to be run. And also hardware support for watch points, to break on write to a certain address. This makes GDB watch points efficient, not requiring it to single-step and manually decode the instruction to see where it writes.
https://wiki.osdev.org/CPU_Registers_x86#Debug_Registers
Implementing hardware breakpoints using x86 debug register osdev forum thread might be relevant.
Some other ISAs exist without nearly as much HW support for debugging. e.g. without a single-step flag, a debugger might have to always decode the current instruction (pointed to by program counter) to find the next one to be executed, and set a software breakpoint there.
ARM Linux used to do that to implement ptrace
single-step, but that disassembler code was removed from the kernel and now just returns -EIO
. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=425fc47adb5bb69f76285be77a09a3341a30799e is the commit that removed it.
How is Linux kernel live debugging done and what tools are used?
Another option is to use an ICE or JTAG controller, and GDB. This 'hardware' solution is especially used with embedded systems.
But for instance QEMU offers similar features:
start QEMU with a GDB 'remote' stub which listens on 'localhost:1234' :
qemu -s ...
,then with GDB, you open the kernel file
vmlinux
compiled with debug information (you can take a look a this mailing list thread where they discuss the unoptimization of the kernel).connect GDB and QEMU:
target remote localhost:1234
see your live kernel:
(gdb) where
#0 cpu_v7_do_idle () at arch/arm/mm/proc-v7.S:77
#1 0xc0029728 in arch_idle () atarm/mach-realview/include/mach/system.h:36
#2 default_idle () at arm/kernel/process.c:166
#3 0xc00298a8 in cpu_idle () at arch/arm/kernel/process.c:199
#4 0xc00089c0 in start_kernel () at init/main.c:713
Unfortunately, user-space debugging is not possible so far with GDB (no task list information, no memory management unit reprogramming to see different process contexts, ...), but if you stay in kernel-space, that's quite convenient.
info threads
will give you the list and states of the different CPUs
You can get more details about the procedure in this PDF:
Debugging Linux systems using GDB and QEMU.
Related Topics
Process Niceness (Priority) Setting Has No Effect on Linux
Setuid on an Executable Doesn't Seem to Work
Why Can't I Install Any Packages with Ghc 7.8.4 on Raspberry Pi
Inotify Fd - Why Is The Limit Per User Id and Not Per Process
Remote Linux Server to Remote Linux Server Large Sparse Files Copy - How To
Changing File Permissions Linux
Caputre Opengl Window in X11 with Fast Framerate - Possible
Goroutine in Io Wait State for Long Time
Vagrant - How to Mount The Virtualbox Shared Folder? ("Vboxsf" Not Available)
How to Mmap() a Large File Without Risking The Oom Killer
Capture Output of a Bash Command, Parse It and Store into Different Bash Variables
Bluetooth Low-Energy on Linux API
Where Is User's Cron Job Stored After "Crontab -E"
Find Syslog Max Message Length
How to Measure Net Used Disk Space Change Due to Activity by a Given Process in Linux