none
一个WritFile函数blocked的奇怪问题 RRS feed

  • 问题

  • 问题的现象为:程序开一个线程监听某个端口,接收数据并提供服务,本来是正常的,某一天,向该端口发送请求怎么都得不到回复了。

    经过检查,发现服务线程blocked,查看调用堆栈

    由于不是自己的代码,最后一行抹掉了。最后一行是exe使用boost.log打印日志,其实就是这样

    BOOST_LOG_SEV(log_mt, level)<<boost::filesystem::path(__FILE__).leaf().string()<<":"<<__LINE__<<"]"<<"我自己的日志内容";

    线程blocked的位置已经很明确,写日志时阻塞了,可是为什么WriteFile会阻塞呢?

    在调用堆栈的第三行msvcr100.dll!_wirte_noblock函数中调用WriteFile函数同步写文件,代码如下

    if ( WriteFile( (HANDLE)_osfhnd(fh),
                lfbuf,
                (int)(q - lfbuf),
                (LPDWORD)&written,
                 NULL) )

    WriteFile函数内部实现看不到了,只有反汇编,可以看到WriteFile内部调用了如下函数(KERNALBASE.dll!_WriteFile@20()

    7713BFA3  call        dword ptr [__imp__NtWriteFile@36 (771C960Ch)]

    继续反汇编如下(ntdll.dll!_ZwWriteFile@36())

    _ZwWriteFile@36:
    777BDA50  mov         eax,1A0006h  
    777BDA55  call        dword ptr fs:[0C0h]  
    777BDA5C  ret         24h  
    777BDA5F  nop

    最终阻塞在了call dword ptr fs:[0c0h]这一行

    为什么会阻塞呢?哪位大神能给点意见?

    2016年4月22日 5:29

答案

全部回复

  • WriteFile 函数发生了阻塞,我觉得是在读写文件的时候阻塞,这个是函数本来就是支持异步,同步的操作,所以可能是代码在线程同步的时候出现问题。

    • >>if ( WriteFile( (HANDLE)_osfhnd(fh),
    •            lfbuf,
    •           (int)(q - lfbuf),
    •            (LPDWORD)&written,
    •           NULL) )

    从你的一点点代码中可以看出,你最后一个参数是NULL,也就是说你没有用OVERLAPPEND结构体,并且你的_osfhnd(fh)打开方式是没有用FILE_FLAG_OVERLAPPED这个标志.

    从我的理解来看,OVERLAPPEND 应该是用来做文件的同步的,你不使用这个结构体,我觉得同步会有问题。从msdn文档中只有这个参数涉及到线程同步。

    2016年4月25日 3:29
    版主
  • 感谢您的答复,这个问题确实不好找原因,现象也是只出现了一次,不好排查啊。

    OVERLAPPEND结构体其实是用来做异步输入输出用的,我这里是用的同步写文件,所以不需要OVERLAPPEND

    2016年5月11日 6:38
  • 感谢您的答复,这个问题确实不好找原因,现象也是只出现了一次,不好排查啊。

    OVERLAPPEND结构体其实是用来做异步输入输出用的,我这里是用的同步写文件,所以不需要OVERLAPPEND

    如果后续有什么问题,请随时来论坛发帖子。

    cheng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    2016年5月11日 8:06
    版主