• 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 ”);
             printk(KERN_ERR “hit two ”);
             printk(KERN_ERR “hit three ”);
             printk(KERN_ERR “hit four ”);
             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 ”,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 ”, instruction_pointer(regs));
            //此处是新增的调用单步实现函数
          do_my_step(instruction_pointer(regs));
          /*
            * Setup single step
             */
           kdb_setsinglestep(regs);
         /*
           * Reset delay attribute
           */
          bp->bp_delay = 0;
         bp->bp_delayed = 1;
    }
    6
      实际应用,进入kdb模式后 ,(echo g > /proc/sysrq-trigger)
      输入ss即可实现单步模式(汇编级别的):
      kdb>bp c0339bf8    (在testPara_7函数处设置一个断点)
      kdb>go
      之后kernel运行到此函数,系统进入KDB模式,就可以进行单步调试
      kdb>ss
      ….
      与预想的一致,按两次ss即可打印出一条语句:(可通过串口及minicom观察)
      如: hit one
                 hit two
                 …..
    7
      7.1  总的来说实现了step功能,但是还是存在一些小bug
      7.2  有时间的话,希望能够实现C语言级别的step(对我来说难度太大)
    8
      kgdb_arch_handle_exception函数和自己实践,ARM结构的GKDBb,并没有
      实现step调试功能。
      曾试图去实现kgdb的step功能,由于条件及能力限制没能实现(
      kgdb需要用的一个串口通讯,调试本来也需要单独一条,但是现在只有
      一条共用的),
      int kgdb_arch_handle_exception(int exception_vector, int signo,
              int err_code, char *remcom_in_buffer,
              char *remcom_out_buffer,
              struct pt_regs *linux_regs)
      {
                unsigned long addr;
                char *ptr;
               switch (remcom_in_buffer[0]) {
                          case ‘D’:
                          case ‘k’:
                          case ‘c’:
                          ptr = &remcom_in_buffer[1];
                          if (kgdb_hex2long(&ptr, &addr))
                                        linux_regs->ARM_pc = addr;
                          else if (compiled_break == 1)
                                        linux_regs->ARM_pc += 4;

                         compiled_break = 0;

              return 0;
     }

    return -1;
     }

  • 相关阅读:
    bzoj 2730: [HNOI2012]矿场搭建
    bzoj 1179: [Apio2009]Atm
    strcpy,strlen, strcat, strcmp函数,strlen函数和sizeof的区别
    C语言printf的格式
    C语言中交换两个数值的方法
    C语言中 指针的基础知识总结, 指针数组的理解
    自定义方法实现strcpy,strlen, strcat, strcmp函数,了解及实现原理
    选择排序
    冒泡排序的优化
    storyBoard中取消键盘第一响应
  • 原文地址:https://www.cnblogs.com/pangblog/p/3312929.html
Copyright © 2020-2023  润新知