从帮助文档中,要设置数据访问断点,我们可以使用
var.break <variable> /READWRITE
但是,这只有在我们输入该变量的上下文时才有效。
因为我想编写一个 PRACTICE 脚本来进行自动调试,所以我想在程序运行之前执行此操作。就像是
....
var.break <foo>::<variable> /READWRITE
GO
WAIT !run()
...
有没有办法做到这一点?
从帮助文档中,要设置数据访问断点,我们可以使用
var.break <variable> /READWRITE
但是,这只有在我们输入该变量的上下文时才有效。
因为我想编写一个 PRACTICE 脚本来进行自动调试,所以我想在程序运行之前执行此操作。就像是
....
var.break <foo>::<variable> /READWRITE
GO
WAIT !run()
...
有没有办法做到这一点?
通常,如果局部变量已声明为静态,则只能在局部变量上设置断点(在进入其声明函数之前)。(这不是 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 中。
首先,我们不能为局部变量设置断点。原因是局部变量是自动类型变量,即这些变量仅在函数调用之间和函数退出之间的短时间内分配内存。没有为函数范围之外的局部变量分配内存。因此,不能在局部变量上设置断点。
要解决这个问题,您可以声明全局变量而不是局部变量,或者声明一个静态局部变量。在静态局部变量的情况下,分配的内存保留在定义它的函数范围之外。通过这样做,您可以自动化您的测试,但局部变量无济于事。