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内核为什么会被阻塞


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值