断点不能在gdb中使用QEMU模拟cortex-a8

时间:2018-01-15 22:47:41

标签: c gcc arm gdb qemu

我正在测试在ARM7TDMI中运行的一些简单代码,因为我还没有在QEMU上找到ARM7TDMI模拟器,我使用了Cortex-a8(我不确定这是否会导致bug,总新手)。登记/> 这就是我运行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) 

有没有人对这里发生的事情有任何想法?感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:0)

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

有些事情导致你意外地以低地址0x8结束,你需要找出它是什么。要么你真的跳到0x8,要么你已经采取了例外。查看每台机器指令级别的执行情况会告诉您它是什么。

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

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

我已经按照概率的粗略顺序列出了你的情况,但无论如何单一机器指令步进应该确定发生了什么。