Chinaunix首页 | 论坛 | 博客
  • 博客访问: 416252
  • 博文数量: 55
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 3458
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-18 20:37
个人简介

哈哈

文章分类

全部博文(55)

分类: 嵌入式

2014-05-20 22:34:12

内核有spinlock的调试选项,在spinlock被获取时会记录它的owner。
owner是一个struct task_struct指针,在owner里有pid字段,通过pid就能确认是哪个进程持有锁。

自己做了个实验,在同一个函数里两次调用spin_lock,直接锁死,然后用kdb结合gdb来找锁的持有者,可行。
(关于本文中kdb和gdb的使用方法见http://blog.chinaunix.net/uid-26517122-id-4263265.html)
=======================================================================

(1) 确认内核中打开编译选项 CONFIG_DEBUG_SPINLOCK=y
(2) 挂死的时候进kdb
(3) bt看到spinlock调用栈,找到lock地址
0xc2481ebc 0xc1158e24 _raw_spin_lock+0xbd (0xc241a2b0)
0xc2481ee0 0xc1246815 _spin_lock+0x22 (0xc241a2b0)
0xc2481efc 0xf8408156 [network]tcp_write_timer+0x7f (0xc241a280)
0xc2481f10 0xc1030bbf run_timer_softirq+0x1c1
0xc2481f60 0xc102b0ac __do_softirq+0xa7
0xc2481f8c 0xc102b173 do_softirq+0x26
0xc2481f98 0xc102b256 irq_exit+0x29
0xc2481fa0 0xc100e33a smp_apic_timer_interrupt+0x6f (invalid)
0xc2481fb0 0xc1003236 apic_timer_interrupt+0x2a (invalid, invalid, invalid)

在这里lock的地址是0xc241a2b0,也就是&lock的值,是函数的参数


(4) 根据偏移量得到lock指向的结构体中的owner字段的内存地址
gdb vmlinux......(gdb) p ((spinlock_t *)0)->owner
Cannot access memory at address 0xc

gdb p/x  0xc+0xc241a2b0
$1 = 0xc241a2bc

(5) 根据偏移量得到owner结构体中的pid字段的内存地址
gdb   p ((struct task_struct *)0)->pid
Cannot access memory at address 0x204

gdb p/x 0x204+0xc241a2bc
$2 = 0xc241a4c0

(6) 在kdb中查看pid的值[0]
kdb>  md 0xc241a4c0
00000325 00000325 f73c8000 f73c8000   %...%.....<...<.
所以pid是0x325=805

(7) 在kdb中ps看到pid 805是xxx进程,所以锁的持有者是xxx
阅读(6329) | 评论(1) | 转发(2) |
给主人留下些什么吧!~~

CU博客助理2014-07-11 15:40:44

专家点评:能把自己的项目经验通过代码和易懂的语言写出来与大家共享,真正达到了交流的目的。各个博文之间有连贯性,形成了一个问题的完整的解决方案。一个不错的代码共享交流的经历。(感谢参与原创评选活动,结果即将公布)