簡體   English   中英

條件數據觀察點在 ARM GDB 中不起作用

[英]Conditional data watchpoint doesn't work in ARM GDB

我的意圖是能夠捕捉到全局變量何時具有某個確切值。 GDB 有數據觀察點,據此可以實現。

考慮為 x86 Linux 編寫的這個簡單程序:

int myVar = 0;

void debug_watchpoints() {
    for(int i=0; i < 2000; i++) {
        myVar++;
    }
}

int main() {
    debug_watchpoints();
    return 0;
}

編譯程序

gcc -o main -ggdb3 -Og main.c

並使用 GDB 開始調試:

max@PC-LT-23:~/stackoverflow$ gdb ./main
GNU gdb (Ubuntu 8.3-0ubuntu1) 8.3
Copyright (C) 2019 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-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 ./main...
(gdb) b main 
Breakpoint 1 at 0x1146: file main.c, line 9.
(gdb) start
Temporary breakpoint 2 at 0x1146: file main.c, line 9.
Starting program: /home/max/stackoverflow/main 

Breakpoint 1, main () at main.c:9
9   int main() {
(gdb) watch myVar if myVar==1337
Hardware watchpoint 3: myVar
(gdb) continue
Continuing.

Hardware watchpoint 3: myVar

Old value = 1336
New value = 1337
debug_watchpoints () at main.c:4
4       for(int i=0; i < 2000; i++) {
(gdb) 

如您所見,它恰好在變量設置為 1337 的時間點停止了程序。

考慮完全相同的程序,使用arm-none-eabi-gcc為具有 Cortex-M4F 內核的 STM32L476RG 微控制器編譯。 這里使用的 IDE 是 STM32(又名 Eclipse)的 System Workbench,項目由 STM32CubeMX 生成。

現在啟動openocd

Open On-Chip Debugger 0.10.0+dev-00021-g524e8c8 (2019-04-12-08:33)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
srst_only separate srst_nogate srst_open_drain connect_assert_srst
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
padded zone erase set to 1
adapter speed: 8000 kHz
adapter_nsrst_delay: 100
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 8000 kHz
Info : STLINK v2.1 JTAG v34 API v2 M25 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 0.011074
Error: target voltage may be too low for reliable debugging
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Stlink adapter speed set to 4000 kHz
Info : STM32L476RGTx.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
Info : accepting 'gdb' connection on tcp/3333
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08001340 msp: 0x20018000

main function 中設置斷點,然后像以前一樣設置觀察點。 此外,在執行debug_watchpoints() function 后設置斷點。

GNU gdb (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 8.3.0.20190709-git
Copyright (C) 2019 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 "--host=x86_64-linux-gnu --target=arm-none-eabi".
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".
(gdb) Reset_Handler () at ../startup/startup_stm32l476xx.s:63
63        ldr   sp, =_estack    /* Set stack pointer */

Temporary breakpoint 3, main () at ../Src/main.c:65
65      {

(gdb) watch myVar if myVar==1337
Hardware watchpoint 4: myVar
(gdb) info breakpoints
Num     Type           Disp Enb Address    What
2       breakpoint     keep y   0x08000f46 in main at ../Src/main.c:70
4       hw watchpoint  keep y              myVar
        stop only if myVar==1337
(gdb) 

繼續程序時,它現在會在每次使用SIGTRAP修改變量時停止,無論是否滿足條件。

Program received signal SIGTRAP, Trace/breakpoint trap.
0x08000ec2 in debug_watchpoints () at ../Src/main.c:54
54              for(int i=0; i < 2000; i++) {
(gdb) continue
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x08000ec2 in debug_watchpoints () at ../Src/main.c:54
54              for(int i=0; i < 2000; i++) {
(gdb) continue
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x08000ec2 in debug_watchpoints () at ../Src/main.c:54
54              for(int i=0; i < 2000; i++) {
(gdb) info breakpoint
Num     Type           Disp Enb Address    What
2       breakpoint     keep y   0x08000f46 in main at ../Src/main.c:70
4       hw watchpoint  keep y              myVar
        stop only if myVar==1337
(gdb) print myVar
$2 = 3

我可以根據需要繼續多次,每次更改變量時它都會中斷。

在我的“調試堆棧上的 memory 損壞”的場景中,我真的需要 GDB 來正確評估條件,否則程序會停止一千次或更多次(每次恰好位於此 ZCD69B4957F06CD818D7BF3D618 位置的變量發生變化)不僅在特定時間將特定值寫入其中以捕獲錯誤。

為什么arm-none-eabi-gdb的行為與正常的gdb 錯誤是否在於 Cortex-M4 硬件調試功能arm-none-eabi-gdbopenocd作為 GDB 服務器?

我所知道的軟件都沒有開箱即用。 |當我使用 DWT 時,我通常在我的軟件中設置它。 我還沒有找到任何方法通過 gdb 的任何變體對其進行編程(手動設置寄存器除外 - 但它太煩人了)

如前所述,openocd(您正在使用的調試器橋接器)中沒有有效的實現。

您可以通過 sw 設置。 這里有一個小片段。 COMP2、FUNCTION2、COMP1 和 FUNCTION1 是 DWT 寄存器。 請注意,您需要使用兩個鏈接在一起的比較器。 並非所有 Cortex-m 實現都支持這些功能,也不是所有比較器都是可鏈接的,這取決於您的芯片。 此外,捕獲似乎是異步的。 一般來說,我的電腦在觸發后會停止一些指令。

DWT->COMP2 = <address to compare>;
DWT->FUNCTION2 = 0;
DWT->COMP1 = <word to compare>;
DWT->FUNCTION1 = 0x20B06;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM