应用程序冻结时出现奇怪的调用堆栈

我显然在我的一个应用程序中遇到了死锁问题,并开始调查EurekaLog堆栈跟踪。 这是最近的一个:

Call Stack Information:
--------------------------------------------------------------------------------------------------------------------------------------
|Address |Module        |Unit                        |Class                               |Procedure/Method               |Line      |
--------------------------------------------------------------------------------------------------------------------------------------
|*Exception Thread: ID=14208; Priority=0; Class=; [Main]                                                                             |
|------------------------------------------------------------------------------------------------------------------------------------|
|7C82860C|ntdll.dll     |                            |                                    |KiFastSystemCall               |          |
|7C827D27|ntdll.dll     |                            |                                    |ZwWaitForSingleObject          |          |
|77E61C96|kernel32.dll  |                            |                                    |WaitForSingleObjectEx          |          |
|77E61C88|kernel32.dll  |                            |                                    |WaitForSingleObject            |          |
|77E61C7B|kernel32.dll  |                            |                                    |WaitForSingleObject            |          |
|004151C4|MyApp.exe     |sysutils.pas                |TMultiReadExclusiveWriteSynchronizer|WaitForWriteSignal             |16740[1]  |
|004151BC|MyApp.exe     |sysutils.pas                |TMultiReadExclusiveWriteSynchronizer|WaitForWriteSignal             |16740[1]  |
|0041522C|MyApp.exe     |sysutils.pas                |TMultiReadExclusiveWriteSynchronizer|BeginWrite                     |16818[57] |
|004323FB|MyApp.exe     |Classes.pas                 |TDataModule                         |Create                         |11357[1]  |
|004323C0|MyApp.exe     |Classes.pas                 |TDataModule                         |Create                         |11356[0]  |
|007D744D|MyApp.exe     |uRORemoteDataModule.pas     |TRORemoteDataModule                 |Create                         |163[1]    |
|007D7434|MyApp.exe     |uRORemoteDataModule.pas     |TRORemoteDataModule                 |Create                         |162[0]    |
|007DBFAB|MyApp.exe     |Sentrol_Impl.pas            |                                    |Create_Sentrol                 |85[1]     |
|00646952|MyApp.exe     |uROServer.pas               |TROInvoker                          |CustomHandleMessage            |726[11]   |
|00407BFA|MyApp.exe     |system.pas                  |TInterfacedObject                   |_AddRef                        |17972[1]  |
|00404934|MyApp.exe     |system.pas                  |TObject                             |GetInterface                   |9003[8]   |
|00407B1C|MyApp.exe     |system.pas                  |                                    |_IntfClear                     |17817[1]  |
|00404966|MyApp.exe     |system.pas                  |TObject                             |GetInterface                   |9009[14]  |
|004048E8|MyApp.exe     |system.pas                  |TObject                             |GetInterface                   |8995[0]   |
|00407BD7|MyApp.exe     |system.pas                  |TInterfacedObject                   |QueryInterface                 |17964[1]  |
|77E61680|kernel32.dll  |                            |                                    |InterlockedDecrement           |          |
|00407C10|MyApp.exe     |system.pas                  |TInterfacedObject                   |_Release                       |17977[1]  |
|00407B2C|MyApp.exe     |system.pas                  |                                    |_IntfClear                     |17824[8]  |
|004067DF|MyApp.exe     |system.pas                  |                                    |_FinalizeArray                 |15233[100]|
|00407B1C|MyApp.exe     |system.pas                  |                                    |_IntfClear                     |17817[1]  |
|00646577|MyApp.exe     |uROServer.pas               |TROClassFactoryList                 |FindClassFactoryByInterfaceName|619[17]   |
|77E6166C|kernel32.dll  |                            |                                    |InterlockedIncrement           |          |
|00407BFA|MyApp.exe     |system.pas                  |TInterfacedObject                   |_AddRef                        |17972[1]  |
|00646B72|MyApp.exe     |uROServer.pas               |TROInvoker                          |HandleMessage                  |758[1]    |
|006460C5|MyApp.exe     |uROServer.pas               |                                    |MainProcessMessage             |512[98]   |
|00645BAC|MyApp.exe     |uROServer.pas               |                                    |MainProcessMessage             |414[0]    |
|00647184|MyApp.exe     |uROServer.pas               |TROMessageDispatcher                |ProcessMessage                 |929[2]    |
|00647130|MyApp.exe     |uROServer.pas               |TROMessageDispatcher                |ProcessMessage                 |927[0]    |
|00647BCF|MyApp.exe     |uROServer.pas               |TROServer                           |IntDispatchMessage             |1328[27]  |
|00647ABC|MyApp.exe     |uROServer.pas               |TROServer                           |IntDispatchMessage             |1301[0]   |
|0064782F|MyApp.exe     |uROServer.pas               |TROServer                           |DispatchMessage                |1170[11]  |
|006477B4|MyApp.exe     |uROServer.pas               |TROServer                           |DispatchMessage                |1159[0]   |
|006477A9|MyApp.exe     |uROServer.pas               |TROServer                           |DispatchMessage                |1152[1]   |
|0064779C|MyApp.exe     |uROServer.pas               |TROServer                           |DispatchMessage                |1151[0]   |
|00659CB6|MyApp.exe     |uROLocalServer.pas          |TROLocalServer                      |SendRequest                    |57[1]     |
|00659CA4|MyApp.exe     |uROLocalServer.pas          |TROLocalServer                      |SendRequest                    |56[0]     |
|0065A009|MyApp.exe     |uROLocalChannel.pas         |TROLocalChannel                     |IntDispatch                    |99[10]    |
|005EE540|MyApp.exe     |uROClient.pas               |TROTransportChannel                 |Dispatch                       |1884[36]  |
|005EE3FC|MyApp.exe     |uROClient.pas               |TROTransportChannel                 |Dispatch                       |1848[0]   |
|005EEC8F|MyApp.exe     |uROClient.pas               |TROTransportChannel                 |Dispatch                       |2134[27]  |
|00616EC8|MyApp.exe     |PCCS_Intf.pas               |TSentrol_Proxy                      |GetNewValues                   |6585[7]   |
|007CBDB9|MyApp.exe     |ETAROConnectionForm.pas     |TROConnectionForm                   |SyncSentrolUpdateTimerTimer    |855[16]   |
|7C82ABE5|ntdll.dll     |                            |                                    |RtlTimeToTimeFields            |          |
|004D5D9C|MyApp.exe     |Controls.pas                |TControl                            |WndProc                        |5063[0]   |
|004DA05B|MyApp.exe     |Controls.pas                |TWinControl                         |WndProc                        |7304[111] |
|7C81A3AB|ntdll.dll     |                            |                                    |RtlLeaveCriticalSection        |          |
|0042659C|MyApp.exe     |Classes.pas                 |TThreadList                         |UnlockList                     |3359[1]   |
|00426598|MyApp.exe     |Classes.pas                 |TThreadList                         |UnlockList                     |3359[1]   |
|004935BC|MyApp.exe     |Graphics.pas                |                                    |FreeMemoryContexts             |5060[12]  |
|00493524|MyApp.exe     |Graphics.pas                |                                    |FreeMemoryContexts             |5048[0]   |
|004D9799|MyApp.exe     |Controls.pas                |TWinControl                         |MainWndProc                    |7076[6]   |
|004329F4|MyApp.exe     |Classes.pas                 |                                    |StdWndProc                     |11583[8]  |
|7739C09A|USER32.dll    |                            |                                    |CallNextHookEx                 |          |
|004B1343|MyApp.exe     |ExtCtrls.pas                |TTimer                              |Timer                          |2281[1]   |
|00404A30|MyApp.exe     |system.pas                  |                                    |_CallDynaInst                  |9159[1]   |
|004B1227|MyApp.exe     |ExtCtrls.pas                |TTimer                              |WndProc                        |2239[4]   |
|004329F4|MyApp.exe     |Classes.pas                 |                                    |StdWndProc                     |11583[8]  |
|7739C42C|USER32.dll    |                            |                                    |GetParent                      |          |
|7739C45C|USER32.dll    |                            |                                    |GetParent                      |          |
|773A16E0|USER32.dll    |                            |                                    |DispatchMessageA               |          |
|773A16D6|USER32.dll    |                            |                                    |DispatchMessageA               |          |
|004CC234|MyApp.exe     |Forms.pas                   |TApplication                        |ProcessMessage                 |8105[23]  |
|004CC138|MyApp.exe     |Forms.pas                   |TApplication                        |ProcessMessage                 |8082[0]   |
|004CC26E|MyApp.exe     |Forms.pas                   |TApplication                        |HandleMessage                  |8124[1]   |
|004CC264|MyApp.exe     |Forms.pas                   |TApplication                        |HandleMessage                  |8123[0]   |
|004CC563|MyApp.exe     |Forms.pas                   |TApplication                        |Run                            |8223[20]  |
|004CC4B0|MyApp.exe     |Forms.pas                   |TApplication                        |Run                            |8203[0]   |
|007F18B3|MyApp.exe     |MyApp.dpr                   |                                    |                               |215[65]   |

堆栈跟踪似乎是正常的,直到第一个TTimer调用之后,它包含一些垃圾(?),但是结尾包含似乎持有主线程的锁。

我可以相信这个堆栈跟踪吗? 如果没有,什么会导致这种情况,以及我如何避免它?

有关基于此堆栈跟踪的死锁的任何想法? 我不太了解如何创建一个datamodule可以死锁。

我正在使用德尔福2007年。

编辑:我发现一个DbExpress连接在主线程和RemObjects创建的线程之间共享的情况。 解决了这些问题后,应用程序已经运行了12小时以上,没有任何问题。 我会等待一两天,看看问题是否真的消失了。


我在关闭应用程序和在另一个线程中创建一个TForm或TDatamodule时遇到了同样的问题:因为应用程序正在终止,GlobalNameSpace(请参阅其他答案)被锁定(!),所以在另一个线程中创建TRORemoteDataModule锁定。 因为我用另一个锁来等待那个线程,所以我有一个死锁:-(。

在你的情况下,你必须看看其他线程,找到放置锁的那个(并且可能在等待,否则你不会发生死锁)。 我看到一个“SyncSentrolUpdateTimerTimer”:也许你在另一个线程的TDatamodule的创建中做了一个TThread.Synchronize?

编辑:如果你想在死锁时看看其他线程的堆栈:

  • 尝试进程资源管理器 - >进程 - >线程 - >堆栈(但您需要map2dbg.exe将Delphi .map文件转换为Microsoft .dbg文件以查看调试符号)
    http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
    http://code.google.com/p/map2dbg/
  • 尝试我的开源AsmProfiler(采样模式):它有一个“实时视图”来查看所有线程的堆栈,并使用Delphi调试符号(.map,.jdbg等),因此您不需要map2dbg.exe顺便说一句:我做了这个实时视图,因为我使用了进程管理器很多,并且每次使用map2dbg都很恼火)
    http://code.google.com/p/asmprofiler/wiki/ProcessStackViewer

  • 据我所知,EurekaLog应该是可靠的。 如果包含函数< - >地址映射的信息与可执行文件的版本不同,则堆栈跟踪可能会变为无效。

    我使用JCL进行堆栈跟踪日志记录,并将其与map / jdbg文件一起使用。 如果更改可执行文件并保留相同的映射文件,则堆栈日志将不正确,因为函数地址将不同。 所以也许唯一的原因可能是这个。 您还必须区分上次函数调用的真实堆栈跟踪和“通话历史记录”。 我使用通话记录,该记录还列出了记录时所调用的所有功能。 就像你的情况下的TTimer一样。

    典型的堆栈跟踪只包含导致最后一个函数的函数调用。 另一方面,“通话记录”包含在特定时间框架内被调用的所有功能。 如果在主线程旁边有辅助线程(如TTimer),它也会记录他们的行为。 我忘记了这是如何在JCL中调用的,但是如果您在stRawMode中进行跟踪,这是默认行为。

    最后,我可以从堆栈跟踪中看到WaitForSingleObject被调用,最好使用INFINITE参数,因此它永远不会超时。 然后WaitForSingleObject成为信号的条件永远不会全满。

    检查“TRORemoteDataModule”以及它在构造函数中的作用。 因为它看起来只是从TDataModule继承而来,并且宣传了一些自己的逻辑。 这应该是造成死锁的原因。

    编辑:

    好的,我检查了TDataModule代码:

    constructor TDataModule.Create(AOwner: TComponent);
    begin
      GlobalNameSpace.BeginWrite;
      try
        CreateNew(AOwner);
        if (ClassType <> TDataModule) and not (csDesigning in ComponentState) then
        begin
          if not InitInheritedComponent(Self, TDataModule) then
            raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);
          if OldCreateOrder then DoCreate;
        end;
      finally
        GlobalNameSpace.EndWrite;
      end;
    end;
    

    它使用“GlobalNameSpace”单例接口,它是这样定义和实现的:

    var
      GlobalNameSpace: IReadWriteSync;
    
    initialization
    {$IFDEF MSWINDOWS}
      GlobalNameSpace := TMultiReadExclusiveWriteSynchronizer.Create;
    {$ENDIF}
    ...
    

    所以这里是你的锁。 现在有趣的是它发生的原因? 它看起来像一个标准的VCL代码。 也许你可以分享一些关于应用程序正在做什么的更多信息。

    而且,你有办法查找调试输出。 这是在课堂上定义的:

    procedure TMultiReadExclusiveWriteSynchronizer.BeginRead;
    var
      Thread: PThreadInfo;
      WasRecursive: Boolean;
      SentValue: Integer;
    begin
    {$IFDEF DEBUG_MREWS}
      Debug('Read enter');
    {$ENDIF}
    ...
    

    所以如果定义了“DEBUG_MREWS”,你将通过“OutputDebugString”得到调试信息。 它应该解决问题。 对我来说,这看起来像一个组件初始化竞争条件。 :)


    最后一次调用是在TMultiReadExclusiveWriteSynchronizer中,但它不显示在哪个方法中。 那里它可能调用Windows同步功能,并在那里被阻止。 你在使用RemObjects库吗? 那里发生了一些事情。 您可以使用SysInternals Process Explorer配置为下​​载Windows符号,并在进程运行时检查堆栈跟踪,如果以.dbg格式转换Delphi符号,您将拥有整个明确的调用堆栈。

    链接地址: http://www.djcxy.com/p/91045.html

    上一篇: Weird call stack when application has frozen

    下一篇: Open Source Alternatives to Reflector?