日期:2014-05-16  浏览次数:20369 次

KDB支持单步调试功能(ARM架构)

0
   实践发现KDB不支持step调试功能 (本文针对的是arm CotexA9架构,各种架构的实现方式不一样,
   X86的好像已经支持,不过本人没有验证过)
1
   首先看下要调试的代码段
   1.1  C语言
   int  testPara_7(int a, int b,int c,int d, int e,int f,int g)
   {
         printk(KERN_ERR “hit one \n”);
         printk(KERN_ERR “hit two \n”);
         printk(KERN_ERR “hit three \n”);
         printk(KERN_ERR “hit four \n”);
         return 3;
   }  
   1.2  对应的汇编语言  (objdump -d vmlinux)
   c0339bf8 <testPara_7>:
   c0339bf8: e1a0c00d  mov ip, sp
   c0339bfc: e92dd800  push {fp, ip, lr, pc}
   c0339c00: e24cb004  sub fp, ip, #4 ; 0×4
   c0339c04: e59f0020  ldr r0, [pc, #32] ; c0339c2c <testPara_7+0×34>
   c0339c08: eb05bbef  bl c04a8bcc <printk>
   c0339c0c: e59f001c  ldr r0, [pc, #28] ; c0339c30 <testPara_7+0×38>
   c0339c10: eb05bbed  bl c04a8bcc <printk>
   c0339c14: e59f0018  ldr r0, [pc, #24] ; c0339c34 <testPara_7+0×3c>
   c0339c18: eb05bbeb  bl c04a8bcc <printk>
   c0339c1c: e59f0014  ldr r0, [pc, #20] ; c0339c38 <testPara_7+0×40>
   c0339c20: eb05bbe9  bl c04a8bcc <printk>
   c0339c24: e3a00003  mov r0, #3 ; 0×3
   c0339c28: e89da800  ldm sp, {fp, sp, pc}
   c0339c2c: c060bd96  .word 0xc060bd96
   c0339c30: c060bda3  .word 0xc060bda3
   c0339c34: c060bdb0  .word 0xc060bdb0
   c0339c38: c060bdbf  .word 0xc060bdbf
3
   通过分析汇编发现指令的地址都是以4的步长递增的,这种情况就比较号解决了,
   不用去根据不同的汇编指令,改变PC的值。而只需要简单的PC=PC+4即可。
4
   在Debug_core.c 增加函数如下:
   并在头文件中声明:  extern  void do_my_step(unsigned long addr);
void do_my_step(unsigned long addr)
{
     int i=0;
     for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++)
     {

          if (kgdb_break[i].bpt_addr != addr)
              continue;
        //找到地址相匹配的,修改其地址值
         kgdb_break[i].bpt_addr=kgdb_break[i].bpt_addr+4;
         kgdb_break[i].state = BP_SET;
          printk(KERN_ERR “i is %d    kgdb_break[i].bpt_addr is %p\r\n”,i,  kgdb_break[i].bpt_addr);
          break;
    }                                
}
5  修改 kdb_bp.c 中的 kdb_handle_bp 函数如下:
   static void kdb_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
{
       if (KDB_DEBUG(BP))
               kdb_printf(“regs->ip = 0x%lx\n”, instruction_pointer(regs));