条件数据监视点在ARM GDB中不起作用

问题描述 投票:0回答:1

我的意图是能够在全局变量具有某个确切值时进行捕获。 GDB具有data watchpoints,据此可以实现。

考虑这个为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的时间点暂停了程序。

考虑完全相同的程序,对于具有Cortex-M4F内核的STM32L476RG微控制器,用arm-none-eabi-gcc编译。此处使用的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功能中设置了一个断点,然后完全像以前一样设置了监视点。同样,在执行debug_watchpoints()功能后设置断点。

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

我可以继续执行任意多次,每次更改变量时都会中断。

在我的“调试堆栈中的内存损坏的情况下,我真的需要GDB来正确评估条件,否则程序将停止一千次或更多次(每次更改恰好位于此内存位置的变量时, ),而不仅仅是在特定时间将特定值写入其中以捕获错误。

为什么arm-none-eabi-gdb在行为上与正常gdb不同?错误可能出在作为GDB服务器的Cortex-M4硬件调试功能arm-none-eabi-gdbopenocd上吗?

我的意图是能够在全局变量具有某个确切值时进行捕获。 GDB具有数据观察点,可以根据这些数据观察点来实现。考虑一下为x86 Linux编写的简单程序:...

c debugging arm gdb cortex-m
1个回答
0
投票

我所知道的任何软件都不是开箱即用的。 |使用DWT时,通常在软件中进行设置。我没有找到通过gdb的任何变体对其进行编程的任何方法(除了手动设置寄存器外-太烦人了)

© www.soinside.com 2019 - 2024. All rights reserved.