linux设备上的gdb调试,Lniux设备驱动gdb调试

相当于shell的cd命令,pwd显示当前所在目录

(4)程序输出

info terminal用于显示程序用到的终端模式

3.break命令

在GDB中用break命令来设置断点,设置断点方法如下:

(1)break ,指定在函数function处设置断点(停止)

(2)break ,指定行号停止

(3)break+offset / break - offset ,在当前行号前面或后面的offset行停止

(4)break filename:linenum在源文件filename的linenum行处停止

(5)break filename:function,在源文件filename的function函数入口处停止

(6)break *address,在程序运行的内存地址处停止

(7)break,没有指定参数,表示在下一条指令处停止

(8)break ... if,其中...可以是上述的break

,break+offset / break - offset,break

等,在条件成立时停止

4.单步命令

(1)step 单步跟踪,如果由函数调用,则进入该函数,step后面不加count 表示一条条地执行

(2)next 单步跟踪,如果由函数调用,它不会进入该函数,同样地,next后面不加count表示一条条地执行

(3)set step-mode,set step-mode

on用于打开step-mode模式,这样,在进行单步调试时,程序不会因为没有debug信息而不停止,set step-mode

off用于关闭step-mode模式

(4)finish,运行程序,直到当前函数完成返回

(5)until(缩写u),一直在循环体内执行单步,不会退出来

(6)stepi(缩写si)和nexti(缩写ni),用于单步跟踪一条机器码

5.continue命令

当程序被停止后,可以使用continue命令恢复程序的运行直到程序结束或到达下一个断点

6.print命令

在调试程序时,当程序被停止时,可以使用print命令(缩写p),来查看当前程序的运行数据,如下:

(gdb) print sum

$3 = {133, 0, 0, 0, 0, 0, 0, 0, 0, 0}

(gdb) next

Breakpoint 1, add (a=56, b=99) at gdb.c:4

4 return a+b;

(gdb) next

5 }

(gdb) next

main () at gdb.c:24

24 printf("TQ2440 : %d",sum[i]);

(gdb) next

21 for(i = 0;i < 10;i++)

(gdb) next

23 sum[i] = add(array1[i],array2[i]);

(gdb) print sum

$4 = {133, 155, 0, 0, 0, 0, 0, 0, 0, 0}

(gdb)

7.watch命令

watch一般用来观察某个表达式的值是否有变化,如果有变化,马上停止程序执行(比如程序中的i等)

8.examine命令

该命令用来查看内存中地址的值

9.jump命令

一般来说,被调试的程序会按照程序代码的运行顺序依次执行,但是GDB也提供了乱序执行的功能,从而可以让程序随意跳跃

10.signal命令

使用singal命令,可以产生一个信号给调试程序,如中断信号,这非常方便程序的调试,signal的语法为signal

11.return命令

如果在函数中设置了调试断点,在断点后还有语句没有被执行,这是可以调用return命令来强制函数忽略没有执行的语句返回

return //立即返回

return

12.call命令

用于强制调用某函数

call

13.info命令

info命令可以在调试时查看寄存器,断点,观察点和信号等信息

info registers (查看除了否点寄存器以外的寄存器)

info all-registers(查看所有寄存器)

info break(查看断点)

info watchpoints(查看当前社会自的观察点)

info signal(查看那些信号被gdb检测)

14.disassemble命令

disassemble命令用与反汇编,它可以用来查看当前执行时源代码的机器码

disassemble func

(gdb) disassemble add

Dump of assembler code for function add:

0x08048374 : push  ?p

0x08048375 : mov  %esp,?p

0x08048377 : mov  0xc(?p),?x

0x0804837a : add  0x8(?p),?x

=> 0x0804837d : pop  ?p

0x0804837e : ret

End of assembler dump.

(gdb)

Linux内核调试

调试嵌入式Linux内核的方法如下:

1.目标机“插桩”,如打上KGDB补丁,这样主机上的GDB可与目标机的KGDB通过串口或网口通信

2.使用仿真器,仿真器可直接连接目标的JTAG/BDM,这样主机GDB就可以通过与仿真器的通信来控制目标机

3.在目标板上通过printk(),oops,strace等软件方法进行“观察”调试

内核打印信息

在Linux中,内核打印语句printk()会将内核信息输出到内核信息缓冲区,内核信息缓冲区是一个环形缓冲区(ring

buffer),因此,如果塞入的消息过多,就会将之前的消息冲刷掉

printk()定义了8个消息级别,分别为0-7,越低级别(数值越大)的消息越不重要,第0级是紧急事件级,printk()级别定义如下:

#define KERN_EMERG "<0>" /system is

unusable #define KERN_ALERT "<1>" /action

must be taken

immediately #define KERN_CRIT "<2>" /critical

conditions

#define KERN_ERR "<3>" /error

conditions #define KERN_WARNING "<4>" /warning

conditions #define KERN_NOTICE "<5>" /normal

but significant

condition #define KERN_INFO "<6>" /informational #define KERN_DEBUG "<7>"

通过/proc/sys/kernel/printk文件可以调节printk的输出低级

控制台日志级别:优先级高于该值的消息将被打印至控制台

默认的消息日志级别

最低控制台日志级别

默认的控制台日志级别

上述4个值的默认值设置为6,4,1,7

在设备驱动中我们经常需要输出调试或系统的信息,可以直接采用printk(<7>...)输出

使用/proc

在Linux系统中,/proc文件系统十分有用,它用于内核向用户导出信息,而且Linux中很多命令本身通过分析/proc下的文件来完成的,如ps,top等

在Linux系统中,可以用如下函数创建/proc节点:

static inline struct proc_dir_entry *create_proc_entry(const char

*name,

mode_t mode, struct proc_dir_entry *parent);

static inline struct proc_dir_entry *create_proc_read_entry(const char

*name,

mode_t mode, struct proc_dir_entry *base,

read_proc_t

*read_proc, void * data);

create_proc_entry()函数用于创建/proc节点,而create_proc_read_entry()调用create_proc_entry()创建只读的/proc节点,参数name为/proc节点的名称,mode_t

为创建了节点(文件)的权限,parent/base为父目录节点,如果为NULL。则指proc目录

下列函数用于创建/proc目录

struct proc_dir_entry *proc_mkdir(const char *name,struct proc_dir_entry

*parent);

下面是上述两个创建目录和创建节点的一个例子

//创建/proc下的目录

example_dir = proc_mkdir("procfs_example",NULL);

if(ecample_dir == NULL){

rv = -ENOMEM;

goto out;

}

example_dir->owner = THIS_MODULE;

//创建一个例子/proc文件

example_file = create_proc_entry("example_file",0666,example_dir);

if(example_file == NULL){

rv = -ENOMEM;

goto out;

}

...

作为上述函数各返回值proc_dir_entry结构体中包含了/proc节点的度汗还是指针(read_proc_t

*read_proc),写函数指针(write_proc_t *write_proc)以及父节点,子节点信息等.

Linux系统中可用如下函数删除/proc节点

void remove_proc_entry(const char *name,struct proc_dir_entry

*parent);

监视工具

在Linux系统中,strace是一个相当有效的跟踪工具,它的主要特点是可以被用来监视系统调用,我们不仅可以用strace调试一个新开始的程序,也可以调试一个已经在运行的程序,它会得到各调用函数的返回值,如打开函数open(),成功时它会返回一个3(不一定是3),这时我们就可以通过这个返回值就可以知道函数成功与否(之后对fd为3的文件会就行的read(),write()等系统调用)。

内核调试器

kcore

GDB调试器可以把内核作为一个应用程序来调试,在这种方式中,需要给GDB指定未经压缩的内核镜像的文件名和"core"文件,对于一个正在运行的内核,"core文件"就是运行时的内存映像/proc/kcore,因此,使用GDB和kcore调试内核的典型命令如下:

gdb /usr/src/linux/vmlinux /proc/kcore

在gdb /vmlinux

/proc/kcore这种调试方式中,GDB的绝大多数功能都不能使用,如修改内核变量的值,设置断点,单步执行等,可加载模块的symbol并没有包含在vmlinux中,必须使用一些辅助方法才能调试模块,Linux可加载模块是ELF格式的可执行映像,它们被分成几个段

.text:这个段包含模块可执行代码

.bss/.data:这两个段包含模块的变量,在编译时未初始化的变量在.bss段,而被初始化的段在.data段

当一个模块被加载后,在/sys/module目录下会新增一个对应模块的目录,下面是一个例子

[root@cgyl2010 ~]#ls

New0001.ko devgecho hello.c myhello signal.ko wed

backlight etc hello.ko myled.ko sixqd.ko yg.ko

bin fb home myzd sy yubu

cgy fb_test leds opt sys yueyi.ko

cgyled fost.ko lib poll thirdzd.ko yy.ko

cs gui.ko linuxrc proc tmp zd

dev gy mnt root usr

devg hello

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值