gdb调试内核(整理)

1、break 断点

1) 设置断点

      break +offset
      break -offset                      (在当前行号的前面或后面的offset行停住。)
      break filename:linenum   在源文件filename的linenum行处停住。
      break filename:function   在源文件filename的function函数的入口处停住。
      break ... if                            ...可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置break if i=100,表示当i为100时停住程序。
2) 删除断点

      clear               清除所有的已定义的停止点。 
      clear func      清除所有设置在函数上的停止点。
      delete [breakpoints] [range...]    删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)

3)disable和enable断点(disable断点之后,当你还需要使用的时候再enable就可以了)

      disable [breakpoints] [range...]
        disable所指定的停止点,breakpoints为停止点号。如果什么都不指定,表示disable所有的停止点。
     enable [breakpoints] [range...]
        enable所指定的停止点,breakpoints为停止点号。

4)查看断点

      info break


2、List 打印调试程序代码

   ?<linenum>    行号。  
   ?<+> [offset]    当前行号的正偏移量。  
   ?<-> [offset]     当前行号的负偏移量。  
   ?<filename:linenum> 文件的中的行。  
   ?<function>                 函数的代码  
   ?<filename:function> 文件中的函数。  
   ?<*address>               程序运行时的语句在内存中的地址。

扫描二维码关注公众号,回复: 875105 查看本文章

3、print 查看变量
print [</format>] <expr>  
其中参数expr可以是一个变量,也可以是表达式。format表示输出格式,例如,可以用/x来将结果按16进制输出。

format的取值范围有如下几种:  
      ?x 按十六进制格式显示变量。  
      ?d 按十进制格式显示变量。  
      ?u 按十六进制格式显示无符号整型。  
      ?o 按八进制格式显示变量。  
      ?t 按二进制格式显示变量。  
      ?a 按十六进制格式显示变量。  
      ?c 按字符格式显示变量。  
      ?f 按浮点数格式显示变量。

1)查看变量例子
       (gdb) p top
       $16 = 1
       (gdb) p &top
       $17 = (int *) 0x804a014 <top>
       (gdb) p 3+2*5
       $18 = 13
       (gdb) p /x 3+2*5
       $19 = 0xd 

2)查看寄存器的值

       p $eax             查看eax寄存器中的值
       info register    打印所有的寄存器

3)通过print查看文件或者函数中的变量的值

       print file::variable

       print function::variable     如之前使用过的print ohci_rh_resume::ohci->lock,来打印这个锁的相关消息。

4)查看数组的值
      有时候,你需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。你可以使用GDB的“@”操作符,“@”的左边是第一个内存的地址的值,“@”的右边则你你想查看内存的长度。例如,你的程序中有这样的语句:
      int *array = (int *) malloc (len * sizeof (int));
      于是,在GDB调试过程中,你可以以如下命令显示出这个动态数组的取值:
      p *array@len
      如果是静态数组的话,可以直接用print数组名,就可以显示数组中所有数据的内容了。


4、单步调试

在程序执行的时候按下ctrl+c 则停住程序。

在程序停住的地方通过backtrace或者bt或者info stack可以查看调用栈信息

1)next   单步运行,如果有函数调用,他不会进入函数

2)step   单步运行,如果有函数调用,他会进入该函数

3)finish 跳出当前函数,并打印函数返回时的堆栈地址和返回值及参数值等信息。

4)until   跳出一个循环

5)c        继续运行

6)r         运行或者重新运行程序


5、info

1)inifo break  查看断点信息

2)info locals   打印出当前函数中所有局部变量及其值

3)info stack   查看栈中的信息

4)info registers/info all-registers  查看(所有寄存器信息,包括浮点寄存器)

5)info args    查看参数信息


6、

1) 程序运行参数

      set args 可指定运行时参数

      show args 查看设置好的运行参数

2) 运行环境

      set environment varname [=value 设置环境变量

      show environment [varname] 查看环境变量


以上部分转自:

http://www.cnblogs.com/shipfi/archive/2008/08/04/1260293.html

http://wiki.ubuntu.org.cn/index.php?title=%E7%94%A8GDB%E8%B0%83%E8%AF%95%E7%A8%8B%E5%BA%8F&variant=zh-hans




调试mutex死锁

在Kernel Hacking中,配置CONFIG_DEBUG_MUTEX、CONFIG_DETECT_HUNG_TASKS,这样当死锁发生时,默认120S,kernel检测到死锁,同时打印出调用栈。

在代码死锁的地方,在enable了CONFIG_DEBUG_MUTEX的情况下添加这样的代码:

show_stack(<lock>.owner, NULL);

<lock>是你的mutex的变量名,owner是一个struct task_struct *

利用show_stack就可以打印出mutex被谁占用了,和调用该mutex的调用栈


dump_stack:打印当前的backtrace

show_stack:打印指定task_struct的backtrace


以上部分转自:

http://www.cnblogs.com/super119/archive/2013/04/09/3010448.html

猜你喜欢

转载自blog.csdn.net/luckywang1103/article/details/42193163
今日推荐