【问题标题】:Breakpoint not working in gdb with QEMU simulating cortex-a8使用 QEMU 模拟 cortex-a8 的断点在 gdb 中不起作用
【发布时间】:2018-01-15 22:47:41
【问题描述】:

我正在测试一些在 ARM7TDMI 中运行的简单代码,因为我还没有在 QEMU 上找到 ARM7TDMI 模拟器,所以我使用 Cortex-a8 代替(我不确定这是否会导致错误,完全是新手)。
这就是我运行 QEMU 的方式:
qemu-system-arm -machine realview-pb-a8 -cpu cortex-a8 -nographic -monitor null -serial null -semihosting -kernel main.elf -gdb tcp::51234 -S

我要测试的代码很简单,函数LoadContext()SaveContext()是IAR IDE用arm汇编写的,IAR IDE使用ARM7TDMI作为核心。我用 IAR 将这个程序集文件编译成一个目标文件,并将下面的代码链接到 arm-none-eabi-gcc,这会导致不可预知的错误吗? (只是想用 gcc 和 QEMU 代替 IAR...)

int main(void)
{

    Running = &taskA;
    Running->PC = task1;
    Running->SP = &(Running->StackSeg[STACK_SIZE-1]);

    LoadContext();
}

void task1(void)
{
    register int reg_var = 1;
    volatile int vol_var = 1;

    SaveContext();
    reg_var++;
    vol_var++;

    SaveContext();
    reg_var++;
    vol_var++;

    LoadContext();
}

所以,当我在 gdb 中设置断点时,它不起作用,我认为它只会进入无限循环。我查看了初始化过程,是:

(gdb) 
0x000082f6 in __libc_init_array ()
(gdb) 
0x000080e2 in _start ()
(gdb) 
0x000080e4 in _start ()
(gdb) 
0x000080e6 in _start ()
(gdb) 
main () at src/context-demo.c:12
12  int main(void) {
(gdb) 
0x000081ea  12  int main(void) {
(gdb) 
0x00000008 in ?? ()
(gdb) 
0x0000000c in ?? ()
(gdb) 
0x00000010 in ?? ()
(gdb) 
0x00000014 in ?? ()
(gdb) c
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x00000004 in ?? ()
(gdb) c
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x00000004 in ?? ()
(gdb) 

有人对这里发生的事情有任何想法吗?任何帮助表示赞赏,谢谢!

【问题讨论】:

  • 你最终会到达 00000000 而不是你应该在的地方......
  • 嗯...但它应该在循环中执行SaveContext(); reg_var++; vol_var++; LoadContext();...并且它可以与 IAR 一起查找

标签: c gcc arm gdb qemu


【解决方案1】:

如果您告诉 gdb 告诉您它正在执行的汇编指令(“display /3i $pc” 将在每次 gdb 停止时打印接下来的 3 条指令),并且执行单步操作,您会发现这更容易调试个人指令(“stepi”)。

某些事情导致您意外地到达低地址 0x8,您需要找出那是什么。要么你真的跳到 0x8,要么你接受了一个例外。查看每台机器指令级别的执行情况会告诉你它是什么。

这里有一些似是而非的可能性:

  • 可执行文件假设它有 RAM,而 realview-pb-a8 没有 RAM——这通常表现为“无声地写入堆栈(或全局变量)并从堆栈/全局变量中读取返回 0” ,所以如果你在全局中有一个函数指针,或者你尝试将返回地址压入堆栈然后弹出它,你最终会在 0
  • 可执行文件假设它在提供 SVC API 的操作系统下运行 - 在这种情况下,代码将执行 SVC 指令并且您的代码将崩溃,因为在 SVC 异常向量中没有任何东西可以处理它
  • 为错误的 CPU 类型构建的可执行文件并执行 UNDEF 的指令(这将导致执行到地址 0x4,即 undef 向量,但我感觉它的 gdbstub 中有一个 qemu 错误,这可能意味着一个步骤执行一个 UNDEF insn 直到在 UNDEF 向量处执行第一个 insn 之后才会停止)
  • 假定 FPU 始终启用的可执行文件。当 QEMU 像这样执行“裸机”二进制文件时,CPU 会在硬件启动的状态下启动,这会禁用 FPU。因此,除非可执行文件的启动代码显式打开了 FPU,否则任何使用 FPU 的指令都将 UNDEF。

对于您的情况,我已经按照概率的粗略顺序列出了这些,但无论如何,通过机器指令单步执行应该可以确定发生了什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-24
    • 2012-02-19
    • 1970-01-01
    • 2021-10-20
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多