4

从帮助文档中,要设置数据访问断点,我们可以使用

var.break <variable> /READWRITE

但是,这只有在我们输入该变量的上下文时才有效。

因为我想编写一个 PRACTICE 脚本来进行自动调试,所以我想在程序运行之前执行此操作。就像是

....
var.break <foo>::<variable> /READWRITE
GO
WAIT !run()
...

有没有办法做到这一点?

4

2 回答 2

5

通常,如果局部变量已声明为静态,则只能在局部变量上设置断点(在进入其声明函数之前)。(这不是 TRACE32 的限制。在进入声明函数之前,任何调试器都不能在非静态变量上设置断点。)

假设您有这样的功能:

int myFunc(int x) {
    int myVar;        
    static int myStaticVar;      
    /* ... */
}

对于静态局部变量,您可以设置断点

`Var.Break.Set  myFunc\myStaticVar  /ReadWrite`

读/写断点通过使用位于目标 CPU 上的地址比较器来工作。所以这类断点只适用于静态地址。但是,非静态局部变量没有固定地址。它们位于核心寄存器中或相对于调用堆栈上的函数帧指针。

使用命令检查局部变量的位置Var.INFO myFunc\myVar

对于位于调用堆栈上的本地(非静态)变量,您可以使用以下技巧在进入函数之前设置读/写断点:

Var.NEWGLOBAL void * \temp    
Break.Set myFunc /Program /CMD "Var.Break.Set myVar /ReadWrite" /CMD "Var.Set \temp=&myVar" /RESUME 
Break.Set sYmbol.EXIT(myFunc) /Program /CMD "Break.Delete Var.VALUE(\temp)++(Var.SIZEOF(myVar)-1)" /RESUME 

这将设置一个断点,在进入你的函数时停止你的 CPU。当 CPU 在此断点处停止时,调试器将读/写断点设置为变量。第三个命令确保在退出函数时删除读/写断点。(否则读/写断点可能会在完全不同的函数中触发完全不同的变量)

对于位于核心寄存器中的本地(非静态)变量,您通常不能设置读/写断点。然而,一些 CPU 支持核心寄存器上的断点。在这种情况下,您可以像这样设置断点:

Var.Break.Set myFunc /VarReadWrite myFunc\myVar

或者

Var.Break.Set myFunc /RegisterReadWrite R1

第二种情况假设您知道您的变量位于核心寄存器 R1 中。

于 2015-04-13T21:03:50.240 回答
0

首先,我们不能为局部变量设置断点。原因是局部变量是自动类型变量,即这些变量仅在函数调用之间和函数退出之间的短时间内分配内存。没有为函数范围之外的局部变量分配内存。因此,不能在局部变量上设置断点。

要解决这个问题,您可以声明全局变量而不是局部变量,或者声明一个静态局部变量。在静态局部变量的情况下,分配的内存保留在定义它的函数范围之外。通过这样做,您可以自动化您的测试,但局部变量无济于事。

于 2014-05-23T13:54:08.777 回答