38.Linux驱动调试-根据系统时钟定位出错位置

当内核或驱动出现僵死bug,导致系统无法正常运行,怎么找到是哪个函数的位置导致的?

答,通过内核的系统时钟,因为它是由定时器中断产生的,每隔一定时间便会触发一次,所以当CPU一直在某个进程中时,我们便在中断函数中打印该进程的信息

1.先来回忆下

在之前的第5章内核中断运行过程:分析过,当内核中断产生时,会做以下几步:

  • 1)pc-4(计算返回地址值),然后将各个寄存器值存到sp栈里
  • 2)获取中断号,获取sp地址,然后调用asm_do_IRQ()

1.1其中asm_do_IRQ函数原型如下所示:

asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs);  
                         //irq:中断号        *regs:发生中断前的各个寄存器基地址(=sp基地址)

1.2其中pt_regs结构体成员如下图所示,用来保存各个寄存器内容的数组:

2.所以本节目的,修改asm_do_IRQ()函数,添加如下内容:

  • 1)判断irq若等于系统时钟的irq,然后cnt++
  • 2)若在10s后,获取的进程没有改变,便打印:进程名字、PID、(regs-> ARM_pc)-4

(PS: 为什么要打印PC-4?    因为此时的PC是返回地址,而PC-4才是CPU运行的地址)

3.首先来找到系统时钟的中断号irq

输入#cat /proc/interrupt,如下图所示:

其中中断号来自 linux-2.6.22.6\include\asm-arm\arch-s3c2410\Irqs.h

而S3C2410 Timer Tick,就是我们的系统时钟计数值,在内核中就是jiffies这个全局变量,每隔一段时间+1。

所以S3C2410 Timer Tick的中断号为30

4.接下来便来修改asm_do_IRQ()函数

在asm_do_IRQ()中,添加以下带红色的字(#ifdef 1 ...... #endif)

asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
{
         struct pt_regs *old_regs = set_irq_regs(regs);
         struct irq_desc *desc = irq_desc + irq; 
   #ifdef 1
    static pid_t pre_pid;                    //进程号  
    static int cnt=0;                          //计数值
    if(irq==30)          //判断irq中断号,是否等于系统时钟
    {  
        if(pre_pid==current->pid)
        {   
            cnt++;
        }
        else
        {
            cnt=0;   
            pre_pid=current->pid;
        }
        if(cnt==10*HZ)   //超时10s
        {
        cnt=0;
        printk("s3c2410_timer_interrupt : pid = %d, task_name = %s\n",current->pid,current->comm);
        printk("pc = %08x\n",regs->ARM_pc);
        }
}     
#endif
         ... ...
}

1)其中current是一个宏,为task_struct结构体,表示当前运行的进程信息,该宏通过get_current()来获取进程信息,位于include\asm-arm\current.h中

current->pid:当前进程的PID号

current->com:表示当前进程的name

2) HZ也是一个宏,代表每S的频率,比如每隔10ms加1,那么HZ就等于100

5.测试运行

接下来,我们便安装一个带有while(1)死循环的驱动,然后通过测试程序,内核便会一直在while(1)死循环,进入僵死状态。

由于修改了asm_do_IRQ()函数后,所以会打印信息:

5.1 然后便可以通过pc值=bf0000C,就能查找在哪个函数出错

(参考:http://www.cnblogs.com/lifexy/p/8006748.html)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏coding for love

进程与线程,单核与多核1. 简介2. 程序3. 进程4. 线程5. 多进程与多线程的选择6. 小结参考

用户打开浏览器,其实就是打开了浏览器应用程序。那么什么是程序呢?我们常说浏览器是多线程的,JS 是单线程的,那么什么是线程呢?说到线程,和我们常说的进程有什么关...

47730
来自专栏网络

Nginx 系列实用教程#2:性能

协作翻译 原文:Nginx Tutorial #2: Performance 链接:https://www.netguru.co/codestories/ngi...

24460
来自专栏分布式系统进阶

Kafka的消息是如何被消费的?Kafka源码分析-汇总

21130
来自专栏张首富-小白的成长历程

Linux软件包安装--三魔鬼

yum是基于rpm的软件包管理器,他可以使系统管理人员交互和自动化地更细与管理rpm包,他能自动从服务器下载RPM包并安装,他可以自动处理依赖关系,自动安装所有...

35220
来自专栏运维

代理服务器Tengine的研究与测试

1)Nginx(发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议...

33110
来自专栏文渊之博

事务日志还原的次意外的操作失误

前几天新发布的一套程序发生了一次意外的操作失误,程序员修改某个表的指定范围的指定字段的时候,误操作导致更新操作没有执行where,直接引起该表指定字段全部变为更...

21790
来自专栏北京马哥教育

Linux 系统结构详解

Linux系统一般有4个主要部分: 内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管...

67530
来自专栏jeremy的技术点滴

现代Web开发教程系列_02

30970
来自专栏左瞅瞅,右瞅瞅

nc命令详解

NetCat,在网络工具中有“瑞士军刀”美誉,其有Windows和Linux的版本。因为它短小精悍(1.84版本也不过25k,旧版本或缩减版甚至更小)、功能实用...

34710
来自专栏FreeBuf

挖洞经验 | 一个价值$3133.7美金的Google漏洞

在对Google的安全研究中,由于其云服务平台“cloud.google.com” 具备多种功能,感觉有点意思,所以某天我决定来深入测试一下它。

16550

扫码关注云+社区

领取腾讯云代金券