Chinaunix首页 | 论坛 | 博客
  • 博客访问: 789021
  • 博文数量: 264
  • 博客积分: 592
  • 博客等级: 中士
  • 技术积分: 1574
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-24 22:02
文章分类

全部博文(264)

文章存档

2019年(2)

2018年(1)

2017年(1)

2016年(4)

2015年(14)

2014年(57)

2013年(88)

2012年(97)

分类: LINUX

2015-03-24 13:13:34

原文地址:panic函数分析 作者:shenfeng128

在阅读协议栈代码(内核版本2.6.38),在很多地方都看到panic调用,只是知道大体功能,从未具体分析过,也一直想把协议栈的分析过程写下来,很懒,就一有写,算今天是个开始吧。分析panic太艰难啦,涉及的东西太多啦。


  1. /**
  2.  *    panic - halt the system
  3.  *    @fmt: The text string to print
  4.  *
  5.  *    Display a message, then perform cleanups.
  6.  *
  7.  *    This function never returns.
  8.  */
  9. NORET_TYPE void panic(const char * fmt, ...)
  10. {
  11.     static char buf[1024];
  12.     va_list args;
  13.     long i, i_next = 0;
  14.     int state = 0;

  15.     /*
  16.      * It's possible to come here directly from a panic-assertion and
  17.      * not have preempt disabled. Some functions called from here want
  18.      * preempt to be disabled. No point enabling it later though...
  19.      */
  20.     /**
  21.      * 英文注释已经很清晰啦,就是在panic执行过程CPU不能被抢占。
  22.      */
  23.     preempt_disable();
  24.     /**
  25.      * 修改console 级别,以便printk能把消息打印出来。
  26.      */
  27.     console_verbose();
  28. /*
  29.  * Unlock any spinlocks which will prevent 
  30.  * us from getting the
  31.  message out.
  32. * 英文注释没有看多大明白啊,大概意思好像是抑制打印。
  33.  */
  34.     bust_spinlocks(1);
  35.     va_start(args, fmt);
  36.     vsnprintf(buf, sizeof(buf), fmt, args);
  37.     va_end(args);
  38.     printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
  39. #ifdef CONFIG_DEBUG_BUGVERBOSE
  40.     dump_stack();
  41. #endif

  42.     /*
  43.      * If we have crashed and we have a crash kernel loaded let it handle
  44.      * everything else.
  45.      * Do we want to call this before we try to display a message?
  46.      */
  47.     crash_kexec(NULL);
  48.     /××
  49.      × 应该主要是dump CPU寄存器的状态值已经一些堆栈的信息。
  50.      ×/
  51.     kmsg_dump(KMSG_DUMP_PANIC);

  52.     /*
  53.      * Note smp_send_stop is the usual smp shutdown function, which
  54.      * unfortunately means it may not be hardened to work in a panic
  55.      * situation.
  56.      */
  57.     smp_send_stop();
  58.     /××
  59.      × 调用注册到panic时需要特殊处理的函数,如kgdb调试的入口等,
  60.      ×/
  61.     atomic_notifier_call_chain(&panic_notifier_list, 0, buf);

  62.     bust_spinlocks(0);

  63.     if (!panic_blink)
  64.         panic_blink = no_blink;
     /**
      * 如果sysctl配置了panic_timeout > 0则在panic_timeout后重       * 启系统
      */
  1.     if (panic_timeout > 0) {
  2.         /*
  3.          * Delay timeout seconds before rebooting the machine.
  4.          * We can't use the "normal" timers since we just panicked.
  5.          */
  6.         printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout);

  7.         for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP) {
  8.             touch_nmi_watchdog();
  9.             if (i >= i_next) {
  10.                 i += panic_blink(state ^= 1);
  11.                 i_next = i + 3600 / PANIC_BLINK_SPD;
  12.             }
  13.             mdelay(PANIC_TIMER_STEP);
  14.         }
  15.         /*
  16.          * This will not be a clean reboot, with everything
  17.          * shutting down. But if there is a chance of
  18.          * rebooting the system it will be rebooted.
  19.          */
  20.         emergency_restart();
  21.     }
  22. #ifdef __sparc__
  23.     {
  24.         extern int stop_a_enabled;
  25.         /* Make sure the user can actually press Stop-A (L1-A) */
  26.         stop_a_enabled = 1;
  27.         printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom\n");
  28.     }
  29. #endif
  30. #if defined(CONFIG_S390)
  31.     {
  32.         unsigned long caller;

  33.         caller = (unsigned long)__builtin_return_address(0);
  34.         disabled_wait(caller);
  35.     }
  36. #endif
  37.     local_irq_enable();
  38. /**
  39.  *  进行死循环,抢占被禁止,CPU一直运行panic程序中运行。
  40.  */
  41.     for (i = 0; ; i += PANIC_TIMER_STEP) {
  42.         touch_softlockup_watchdog();
  43.         if (i >= i_next) {
  44.             i += panic_blink(state ^= 1);
  45.             i_next = i + 3600 / PANIC_BLINK_SPD;
  46.         }
  47.         mdelay(PANIC_TIMER_STEP);
  48.     }
  49. }
阅读(2478) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~