Linux内核线程死锁或死循环之后如何让系统宕机重启

Linux内核线程死锁或死循环之后如何让系统宕机重启,第1张

在开发内核模块或驱动时,如果处理失误,导致内核线程中出现死锁或者死循环,你会发现,除了重启之外,你没有任何可以做的。这时你的输入不起任何作用,终端(不是指远程的ssh工具)只会在那重复的输出类似BUG: soft lockup - CPU#0 stuck for 67s! [fclustertool:2043],更无奈的是你重启之后导致系统挂起的堆栈信息也看不到,你所能做的就是一遍遍的加调试信息,一遍遍的重启机器(这是我的经历,现在想想很傻)。

这种情况你肯定不是第一个遇到的,所以内核肯定会提供处理这种情况的一些机制。但是如何来找到这些机制在哪个地方,或者说根据什么信息去google呢?最有用的就是这句话BUG: soft lockup - CPU#0 stuck for 67s! [fclustertool:2043],因为这句话提供你的信息量很大。首先,这条信息可以输出,说明即使发生死锁或者死循环,还是有代码可以执行。第二,可以通过这个日志信息,找到对应的处理函数,这个函数所在的模块就是用来处理CPU被过度使用时用到的。所以通过这个事情,可以看到内核打印出的只言片语都有可能成为你解决问题的关键,一定要从重视这些信息,从中找出有用的东西。

我经常看的内核版本是官方的2.6.32内核,这个版本中我找到的函数是softlockup_tick(),这个函数在时钟中断的处理函数run_local_timers()中调用。这个函数会首先检查watchdog线程是否被挂起,如果不是watchdog线程,会检查当前占有CPU的线程占有的时间是否超过系统配置的阈值,即softlockup_thresh。如果当前占有CPU的时间过长,则会在系统日志中输出我们上面看到的那条日志。接下来才是最关键的,就是输出模块信息、寄存器信息和堆栈信息,检查softlockup_panic的值是否为1。如果softlockup_panic为1,则调用panic()让内核挂起,输出OOPS信息。代码如下所示:/** This callback runs from the timer interrupt, and checks

* whether the watchdog thread has hung or not:*/void softlockup_tick(void){int this_cpu = smp_processor_id()

unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu)

unsigned long print_timestamp

struct pt_regs *regs = get_irq_regs()

unsigned long now

/* Warn about unreasonable delays: */

if (now <= (touch_timestamp + softlockup_thresh))returnper_cpu(print_timestamp, this_cpu) = touch_timestamp

spin_lock(&print_lock)

printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]

",

this_cpu, now - touch_timestamp,

current-comm, task_pid_nr(current))

print_modules()

print_irqtrace_events(current)if (regs)show_regs(regs)elsedump_stack()

spin_unlock(&print_lock)

linux死循环退出方法如下:

1、break语句用于跳出linux死循环。continue用于跳过循环中的一个迭代。break语句可用于跳出循环。

2、break语句跳出循环后,会继续执行该循环之后的代码(如果有的话):continue语句中断循环中的迭代,如果出现了指定的条件,然后继续循环中的下一个迭代。

1.一个死循环不大可能把linux搞崩溃,尤其是到2.4以后,内核都有相应的保护机制,多半情况下这种进程会被杀死的。当然,你可以试试提高进程的优先级(这种我没做过,不知道结果,请事先保存好数据,以免不必要的损失)

2.还有,大量地消耗系统内存。这方法也不能成功。

比如:

======================================

#BOF

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#define ONE_K (1024)

int main ()

{

char*some_memory

int size_to_allocate = ONE_K

int megs_obtained = 0

int ks_obtained = 0

while (1) {

for (ks_obtained = 0ks_obtained <1024ks_obtained++) {

some_memory = (char*)malloc(size_to_allocate)

if (some_memory == NULL) exit (EXIT_FAILURE)

sprintf(some_memory, "Hello,World")

}

megs_obtained++

printf("Now allocated %d Megabytes\n", megs_obtained)

}

exit(EXIT_SUCCESS)

}

#EOF

====================

运行之后,

.....

.....

Out of Memory:Killed process 2365

Killed

======================================

系统为了保护自己的安全运行,终止了这个危险的进程。

3.驱动程序出现问题,比如驱动有bug崩溃了,这时间系统就危险了,但现在的社区里面写的开源驱动大都能和内核很好地结合,bug也没抓得差不多了。(关于驱动程序,可以参看Minix作者写的 *** 作系统原理那本书,作者分析,70%的系统崩溃是由于驱动程序引起的,所以minix采用了微内核设计,只把必要的几千行代码放在内核而剩下的都放到了用户层,他认为这样做能极大地提高系统的稳定性。关于微内核的优劣,不好评论,反正我了解一点,GNU中的一个项目是做一个叫做Hurd的微内枋系统,这个项目已经有好几年了,可以去www.gnu.org找相应的文档。

4.其它。(不知道了)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7492546.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-06
下一篇 2023-04-06

发表评论

登录后才能评论

评论列表(0条)

保存