重叠的串口和蓝屏死机

Mar*_*mke 2 delphi bsod serial-port

我创建了一个异步处理串行端口的类.我用它来与调制解调器通信.我不知道为什么,但有时,当我关闭我的应用程序时,我得到蓝屏并重新启动计算机.我一步一步地记录了我的代码,但是当BSOD出现并且我的计算机重新启动时,我记录数据的文件只包含空格.因此我不知道,BSOD的原因是什么.

我仔细查看了我的代码,发现了问题的几个可能原因(我正在寻找可能导致访问未分配内存并导致AV异常的所有原因).

当我重新思考异步操作的想法时,我想到了一些事情.请验证这些是否正确:

1)WaitCommEvent()获取指向重叠结构的指针.因此,如果我在函数内部调用WaitCommEvent()然后离开函数,重叠结构不能是局部变量,对吧?事件掩码变量和事件句柄也是,对吧?

2)ReadFile()和WriteFile()也接受变量的引用或指针.因此,在重叠的读或写操作完成之前,所有这些变量必须是可访问的,对吧?

3)我只调用一次WaitCommEvent()并在循环中检查其结果,同时做其他事情.因为我不知道如何终止异步操作(是否可能?),当我销毁保持串口句柄的类时,我首先关闭句柄,然后在使用的重叠结构中等待事件调用WaitCommEvent()函数时.我这样做是为了确保为comm事件异步等待的线程不会访问被破坏的类的任何字段.这是个好主意还是愚蠢的?

try
  CloseHandle(FSerialPortHandle);
  if Assigned(FWaitCommEvent) then
    FWaitCommEvent.WaitFor(INFINITE);      
finally
  FSerialPortHandle := INVALID_HANDLE_VALUE;
  FreeAndNil(FWaitCommEvent);
end;
Run Code Online (Sandbox Code Playgroud)

在我注意到所有这些之前,第一点和第二点中提到的大多数变量都是调用上述三种方法的函数的局部变量.可能是BSOD的原因还是我应该在代码中查找其他一些错误?

当我更正代码时,BSOD停止发生,但这可能是巧合.你怎么想?

任何想法将不胜感激.提前致谢.


我阅读了CancelIo()函数文档,它声明此方法取消了调用线程发出的所有I/O操作.如果我知道WaitCommEvent()是由与调用CancelIo()的线程不同的线程发出的,那么在调用CancelIo()之后等待FWaitCommEvent是否可以?

  if Assigned(FWaitCommEvent) and CancelIo(FSerialPortHandle) then
  begin
    FWaitCommEvent.WaitFor(INFINITE);
    FreeAndNil(FWaitCommEvent);
  end;
Run Code Online (Sandbox Code Playgroud)

我检查了在这种情况下发生了什么,调用这段代码的线程没有陷入死锁,即使它没有发出WaitCommEvent().我在Windows 7上测试过(如果重要的话).我可以保留代码,还是危险?也许我误解了文档,这就是我的问题的原因.我为提出这么多问题而道歉,但我真的需要确定一下.

谢谢.

bk1*_*k1e 5

作为标准用户运行的应用程序永远不能导致错误检查(即BSOD).(并且以管理员身份运行的应用程序必须完全不受此限制.)要么遇到驱动程序错误,要么硬件坏了.

默认情况下,Windows配置为在%SystemRoot%\minidump发生错误检查时保存minidump .您可以通过在WinDbg中加载minidump文件,配置WinDbg以使用Microsoft公共符号存储,以及!analyze -v在WinDbg中运行命令来确定有关崩溃的更多信息.至少,这应该确定哪个驱动程序可能有故障(虽然我猜它是你的调制解调器驱动程序).