DirectFB Console Bug调查

问题现象描述:

            BDJ光盘播放程序(ProcBDJ)与Youtube播放程序(ProcY)相互切换时,系统挂机(Hangup)


问题调查 Step1:

           首先通过对比问题发生时与不发生时的Log文件,发现系统在启动DirectFB时挂机。


问题调查Step2:

         进一步分析DirectFB的启动过程:(代码版本0.9.25)

文件dfb/src/core/Core.c 行287

dfb_core_create()

         ↓

dfb/lib/fusion/Arena.c    行502

函数fusion_arena_enter()

       ↓

dfb/src/core/Core.c 行916

函数dfb_core_arena_initialize()

      ↓

dfb/src/core/Core.c 行839

函数dfb_core_initialize()

     ↓

dfb/src/core/core_parts.c 行72

函数dfb_core_part_initialize()

     ↓

dfb/systems/fbdev/Fbdev.c 行446

函数system_initialize()

      ↓

dfb/systems/fbdev/vt.c 行177

函数dfb_vt_initialize()

     ↓

while (ioctl( dfb_vt->fd0,VT_WAITACTIVE, dfb_vt->num ) < 0) {  // Hangup

 

开始调查时,一直不是很明白为什么会在这里挂住。

因为代码的前几行有如下代码:

while (ioctl( dfb_vt->fd0,VT_ACTIVATE, dfb_vt->num ) < 0)

代码上暂时看不出原因,但凭着多年的经验,直观上感觉是console的多进程共享使用冲突。


暂时解决方案:

DirectFB的配置文件(.directfbrc)文件里添加如下选项: no-vt


进一步分析linux内核,发现Block的原因如下:

正常流程:

dfb/systems/fbdev/vt.c 行167

函数dfb_vt_initialize

while (ioctl( dfb_vt->fd0,VT_ACTIVATE, dfb_vt->num ) < 0) {


kernel/linux-2.6.21.5/drivers/char/vt.c

执行LINUX Kernel的set_console函数

kernel/linux-2.6.21.5/drivers/char/vt.c行2208

执行schedule_console_callback

kernel/linux-2.6.21.5/drivers/char/vt.c 行2163

函数console_callback→执行change_console函数

kernel/linux-2.6.21.5/drivers/char/vt_ioctl.c 行1245

函数complete_change_console→vt切换OK。

 

dfb/systems/fbdev/vt.c 行177近く

函数: dfb_vt_initialize

while (ioctl( dfb_vt->fd0,VT_WAITACTIVE, dfb_vt->num ) < 0)

kernel/linux-2.6.21.5/drivers/char/vt_ioctl.c 行1054

vt_waitactive函数里,vt== fg_console→正常返回。(fg_console为当前console的ID。)

 

NG流程:

bdh_dfb/systems/fbdev/vt.c 行167

函数dfb_vt_initialize

while (ioctl( dfb_vt->fd0,VT_ACTIVATE, dfb_vt->num ) < 0) {

kernel/linux-2.6.21.5/drivers/char/vt.c

执行LINUX Kernel的set_console函数

ファイル:bdh_kernel/linux-2.6.21.5/drivers/char/vt.c行2208

函数schedule_console_callback

ファイル: bdh_kernel/linux-2.6.21.5/drivers/char/vt.c 行2163

函数console_callback→执行change_console函数

kernel/linux-2.6.21.5/drivers/char/vt_ioctl.c 行1220

函数complete_change_console没有被执行。 ★差别点 

if (vc->vt_mode.mode == VT_PROCESS) {

                /*

                 * Send the signal as privileged - kill_pid()will

                 * tell us if the process has gone or somethingelse

                 * is awry

                 */

                if(kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {

                        /*

                         * It worked. Mark the vt to switch to and

                         * return. The process needs to send us a

                         * VT_RELDISP ioctl to complete the switch.

                         */

                        vc->vt_newvt= new_vc->vc_num;

                        return; ★異常返回。

                }


dfb/systems/fbdev/vt.c 行177

函数 dfb_vt_initialize

while (ioctl( dfb_vt->fd0,VT_WAITACTIVE, dfb_vt->num ) < 0) ↓

kernel/linux-2.6.21.5/drivers/char/vt_ioctl.c 行1054

vt_waitactive関数hangup。 


总结:

    对于这类系统性Bug,最好的分析方法还是做Log比对,分析差异点。

   中间有两个难关:  1〉到底挂在哪个模块

                                   2〉Linux内核为什么会被阻塞


你可能感兴趣的:(linux,kill,callback,Youtube,Signal,linux内核)