llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
26.88k stars 11.03k forks source link

Hardware breakpoint not hint when set specify load addresses for sections #96616

Open YaowenGuo opened 2 weeks ago

YaowenGuo commented 2 weeks ago

I'm using lldb connect QEMU to debug linux kernel. The linux kernel been load to 0x40200000, So I have to use target modules load to defining load addresses for sections. But when set this, the hardware breakpoint can't be hint. Is is a bug?

  1. Build the latest linux kernel for ARM64.
  2. Launch QEMU to debug kernel
    qemu-system-aarch64 -machine virt,accel=hvf -cpu host  \
    -kernel arch/arm64/boot/Image \
    -append "nokaslr"\
    -nographic \
    -m 2G \
    -s \
    -S
  3. Launch lldb and connect to QEMU
    lldb vmlinux
    (lldb) gdb-remote 1234
    (lldb) breakpoint set -H -a 0x41e300e8
    (lldb) c
  4. This will successfully hint this breakpoint. But when use target modules load to specify debug symbol addresses for sections.
    (lldb) target modules load --file vmlinux .head.text 0x40200000 .text 0x40210000 .rodata.text 0x41e2b800 .init.text 0x41e40000

    the section load address .text 0x40210000 .rodata.text 0x41e2b800 .init.text 0x41e40000 may be different when linux version is different. You need use readelf to virtual address in vmlinux. and calculate:

    
    Section load address = Sections start address - (Linux Entry address  - Qemu load address)

e.g. .rodata.text readelf -S out/arm64/vmlinux There are 51 section headers, starting at offset 0x17316b88: Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 1] .head.text PROGBITS ffff800080000000 010000 010000 00 AX 0 0 65536 [19] .rodata.text PROGBITS ffff800081c2b800 1c3b800 005800 00 AX 0 0 2048

0xffff800081c2b800 - ( 0xffff800080000000 - 0x40200000) = 0x41e2b800

5. After set this.  The breakpoint will not be hit regardless of whether the virtual or physical address is used to set the breakpoint.
set breakpoint by physical address:

(lldb) breakpoint set -H -a 0x41e300f4

set breakpoint by virtual address:

(lldb) breakpoint set -H -a 0xffff800081c300f4 (lldb) c


The breakpoint will not be hit now!!! I think it may be a bug of lldb. When I replacing the debugger's client with gdb, all breakpoints can be hit, including soft breakpoints.
YaowenGuo commented 2 weeks ago

My environment is: OS: Mac OS 14.5 PC: Macbook Pro M2 Max QEMU: 9.0.1 LLDB: 18.1.7 Linux kernel version: 6.10-rc4

llvmbot commented 2 weeks ago

@llvm/issue-subscribers-lldb

Author: 郭耀文 (YaowenGuo)

I'm using lldb connect QEMU to debug linux kernel. The linux kernel been load to 0x40200000, So I have to use `target modules load` to defining load addresses for sections. But when set this, the hardware breakpoint can't be hint. Is is a bug? 1. Build the latest linux kernel for ARM64. 2. Launch QEMU to debug kernel ``` qemu-system-aarch64 -machine virt,accel=hvf -cpu host \ -kernel arch/arm64/boot/Image \ -append "nokaslr"\ -nographic \ -m 2G \ -s \ -S ``` 3. Launch lldb and connect to QEMU ``` lldb vmlinux (lldb) gdb-remote 1234 (lldb) breakpoint set -H -a 0x41e300e8 (lldb) c ``` 4. This will successfully hint this breakpoint. But when use `target modules load` to specify debug symbol addresses for sections. ``` (lldb) target modules load --file vmlinux .head.text 0x40200000 .text 0x40210000 .rodata.text 0x41e2b800 .init.text 0x41e40000 ``` the section load address `.text 0x40210000 .rodata.text 0x41e2b800 .init.text 0x41e40000` may be different when linux version is different. You need use readelf to virtual address in vmlinux. and calculate: ``` Section load address = Sections start address - (Linux Entry address - Qemu load address) e.g. .rodata.text readelf -S out/arm64/vmlinux There are 51 section headers, starting at offset 0x17316b88: Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 1] .head.text PROGBITS ffff800080000000 010000 010000 00 AX 0 0 65536 [19] .rodata.text PROGBITS ffff800081c2b800 1c3b800 005800 00 AX 0 0 2048 0xffff800081c2b800 - ( 0xffff800080000000 - 0x40200000) = 0x41e2b800 ``` 5. After set this. The breakpoint will not be hit regardless of whether the virtual or physical address is used to set the breakpoint. set breakpoint by physical address: ``` (lldb) breakpoint set -H -a 0x41e300f4 ``` set breakpoint by virtual address: ``` (lldb) breakpoint set -H -a 0xffff800081c300f4 (lldb) c ``` The breakpoint will not be hit now!!!