System Request 进入KDB模式过程详解

0
  echo g > /proc/sysrq-trigger
  怎么让系统停下来,进入进入KDB循环?
1
  需要简单了解下:Linux Magic System Request
2
  在sysrq数组中我并没有发现注册”g”对应调用的函数,可是调试的时候确实生效了
  static struct sysrq_key_op *sysrq_key_table[36] = {
 &sysrq_loglevel_op,  /* 0 */
 &sysrq_loglevel_op,  /* 1 */
 &sysrq_loglevel_op,  /* 2 */
        ……
 &sysrq_term_op,   /* e */
 &sysrq_moom_op,   /* f */
 /* g: May be registered for the kernel debugger */
 NULL,    /* g */
 NULL,    /* h – reserved for help */
        ……
   }
   这里的时候为空,不知道在哪里绑定的
   头脑转不过弯,在内核中查找 sysrq_key_table数组(一般来说不会直接操作数据结构),结果没有发现有注册
   其实直接搜索register_sysrq_key就可以(这个后来才知道的)
3
  最后用了最笨的方法:
  3.1  driver/char/sysrq.c __handle_sysrq函数中添加打印函数地址
       void __handle_sysrq(int key, struct tty_struct *tty, int check_mask)
       {

              op_p = __sysrq_get_key_op(key);
             //此行为添加的
              printk(KERN_ERR”key is %d op_p func pointer is %p , %d:\n”,key,op_p->handler,op_p->handler);
       }
       运行时输出: 
       [  184.269194] key is 103 op_p func pointer is c00c8238 , -1072922056:

  3.2  objdump -s vmlinux > linux
       或者在System.map中查找
  3.3  以下是查找对应的结果:
       c00c8238 t sysrq_handle_dbg  
4
  static struct sysrq_key_op sysrq_dbg_op = {
 .handler = sysrq_handle_dbg,
 .help_msg = “debug(G)”,
 .action_msg = “DEBUG”,
  };
  //模块加载的时候,就注册到SYSRQ数组里面去了
  #ifdef CONFIG_MAGIC_SYSRQ
  register_sysrq_key(‘g’, &sysrq_dbg_op);
  #endif
5
   echo g > /proc/sysrq-trigger
              —sysrq_handle_dbg
                      —> arch_kgdb_breakpoint
   static inline void arch_kgdb_breakpoint(void)
   {
        //这个会触发一个trap:软中断,arm与X86的实现有些不一样
        //x86是直接插入0XCC(int 3),arm则是发现没有这个指令触发一个trap
         asm(“.word 0xe7ffdeff”); 
   }
6
   之后进入trap处理函数中
   kgdb_handle_exception
             —>kdb_stub
                  —>kdb_main_loop
                         —>kdb_local
   在kdb_local循环中接收用户输入的命令(go , bp , rd 等)

 

你可能感兴趣的:(request)