程序死循环/卡锁问题定位与分析

死循环/卡锁之代码段定位

  1. pstack 进程号
    pstack是通过采集某个时间点,当前进程调用函数的情况,通过多次调用pstack,发现某个函数一直出现,那么,绝大多数情况下,该函数出现(死循环or死锁)。假设func函数出现的概率很高。
    假设就是出现了死锁、死循环,那么这两种情况有所不同。
    (1)死锁:pstack显示卡死的代码行永远是某一行,且该行代码卡在锁处!(但是这种情况并不一定都是死锁,也有可能是死循环导致的),比如:
    void timer_proc() {  // 定时器
        LOCK(A);
        {
       		while(1) { } //  死循环,拿到A锁
    	}
        UNLOCK(A);
    }
    void process() {
    	LOCK(A);  // 此时,想拿A锁,但是A锁被timer_proc函数拿到,且由于死循环,A锁不能释放,出现的现象是代码卡在该行!
    	UNLOCK(A);  
    }
      这种情况,pstack查看的现象:
      1. timer_proc()函数会一直存在,且代码卡在 while(1) {} 循环代码段附近
      2. 会一直卡在process()函数的LOCK(A)代码行
      误解:由于一直卡在LOCK(A)锁,第一印象会误以为发生了卡锁
      本质上:该现象却是由于死循环导致的。
    
    (2)死循环:pstack显示卡死的代码一直在某个函数范围内,但是行号会在函数内有所变化
  2. top命令、死循环/死锁
    如果某进程出现死循环,那么使用top查看cpu使用率时,将发现该进程cpu占用率会很高,达到100。
  3. gdb调试进程,分析死循环(断点区间:由大变小)
    1-首先,将断点打到函数(大区间),然后C,发现C过很久也一直卡主,说明程序可能在该函数内的某个代码段死循环了,导致没法重新进来
    2-然后,将断点打到pstack显示的行号处(小区间),执行C,如果是死循环,C将会立刻退出,多次C,会一直退出(退出说明程序一直经过该行号)
    3-最后,如果出现上述情况,那绝大多数是死循环了!此时应该用gdb打印各个变量的值,分析代码逻辑,证明的确是死循环。

卡锁原因

上面说的很清楚,死锁的现象是pstack一直卡在某一行,此时,查看代码行,如果发现该代码行的确是LOCK,那么99%是死在这个锁上!(程序死在某个锁上的原因分析)

1-锁A被一个进程持有,且进程没有解锁;导致其他进程想加锁A,就会被卡住

进程没解锁的原因:
	1- LOCK(); 死循环; UNLOCK()
	2- LOCK();UNLOCK()

2-AB锁:需要分析代码,查看是否发生AB、BA加锁顺序

问题解决之gdb调试

查看所有线程的堆栈:thread apply all bt
切换到某个线程:thread 线程号

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值