【问题标题】:Application crash for unknown reasons on WinXP应用程序在 WinXP 上因未知原因崩溃
【发布时间】:2013-08-10 18:07:44
【问题描述】:

我有 Delphi XE3,Windows 7 Pro 64bit。 我的应用程序在我的 PC 上运行良好,但我的用户告诉我应用程序在他们的 Win XP 上启动时崩溃,并且在他们的 Win 7 上也 (!!)。

我尝试在我的 Win 7 上运行该应用程序,但以普通用户(没有管理员)身份登录 - 它可以工作。 所以现在我已经用 Windows XP 安装了虚拟机,并且真的 - 应用程序在启动时崩溃了。

我需要找出问题所在,但我无能为力。

就我不能使用调试器而言(我没有在那个 VM 上安装 Delphi), 我试图在我的应用程序的各个地方放置一些MessageBox(0, 'Hello', 'Test', MB_OK); 以捕捉它发生的地方,这就是我发现的:

我的项目源中有这个:

MessageBox(0, 'Hello', 'Test', MB_OK); // shows OK
Application.CreateForm(TfMain, fMain);
MessageBox(0, 'Hello', 'Test', MB_OK); // doesn't show - crash before this line

这是在我的主窗体fMainOnCreate 函数中:

procedure TfMain.FormCreate(Sender: TObject);
begin
  MessageBox(0, 'Hello', 'Test', MB_OK); // doesn't show - crash before this line
  ...

那么这个应用会在哪里崩溃呢?
甚至OnCreate 中的第一行都没有执行....
我不知道...有人吗?

不知道这是否重要:我在 fMain uses 子句的 interfaceimplementation 下有一些单位。我应该看那里吗?但是在我的主窗体的OnCreate 之前会发生什么?

【问题讨论】:

  • 您无法调试,因为您的 VM 上没有安装 Delphi。您知道有几种非常简单的方法可以解决这个问题,对吧?
  • @Rob Kennedy 嗯,如果我知道,我会这样做。有什么建议吗?
  • 我不是 Rob,但在我的头脑中:1) 在该 VM 上安装 Delphi。 2)使用远程调试器(详见Delphidocumentation)。至于“OnCreate 之前会发生什么?”,请使用源代码。您可以在 Forms.pas 中找到它。
  • “应用程序崩溃”不是可接受的错误描述。如果您能得到实际的错误消息,那可能会导致解决方案。
  • 您在使用中的单位初始化应该无关紧要。它们应该在 formcreate 之前已经执行。但是......在 createform 调用和 formcreate (oncreate) 之间,您的表单上的所有组件都被创建了。可能在其中一个创作中是你的崩溃。你能瘦身/剥离你的表格直到它不崩溃吗?从剥离特殊的非标准组件开始。 (我看到@house of dexter 已经提出了这个建议。)

标签: delphi windows-7 windows-xp delphi-xe3


【解决方案1】:

我终于明白了!

  • 在表单上放置PRINT DIALOG 组件 (TPrintDialog)
  • 在设计时在对象检查器中设置COPIES = 1(或大于默认零)
  • 尝试在未安装打印机的 WinXP 上运行此类应用程序

应用程序在启动时崩溃,在详细信息中您只会看到一些 kernel32.dll 地址...

我没有在没有打印机的 Win 7 上测试它。我周围没有这样的系统...

【讨论】:

    【解决方案2】:

    这是在 VM 上不使用 Delphi 的情况下跟踪此问题的另一种方法...

    • 复制您的项目。
    • 从项目源中删除除主窗体之外的所有单元。
    • 从 XP 启动您的应用程序,看看它是否崩溃。

    • 如果崩溃...然后查看从主窗体中拖入的单元...开始删除它们,直到您的程序停止崩溃。

    • 如果它没有崩溃...开始将单元/表单重新添加到您的项目源中,直到它崩溃。

    您是否安装了 JCL/JVCL(JEDI)?

    如果是这样,请创建一个 Logger...请注意,需要在 MainForm 代码执行之前创建并挂钩 Logger...您还需要从未处理的异常中设置详细的堆栈跟踪, 在 Delphi 中选择->Project/Options/Linker/Map file/Detailed}

    您的 Logger 单元中需要这样的东西

    procedure HookGlobalException(ExceptObj: TObject; ExceptAddr: Pointer; OSException: Boolean);
    var
      a_List: TStringList;
    begin
      if Assigned(TLogger._Instance) then
      begin
        a_List := TStringList.Create;
        try
          a_List.Add(cStar);
          a_List.Add(Format('{ Exception - %s }', [Exception(ExceptObj).Message]));
          JclLastExceptStackListToStrings(a_List, False, True, True, False);
          a_List.Add(cStar);
      // save the error with stack log to file
          TLogger._Instance.AddError(a_List);
        finally
          a_List.Free;
        end;
      end;
    end;
    
    
    initialization
      Lock := TCriticalSection.Create;
      Include(JclStackTrackingOptions, stTraceAllExceptions);
      Include(JclStackTrackingOptions, stRawMode);
    
      // Initialize Exception tracking
      JclStartExceptionTracking;
    
      JclAddExceptNotifier(HookGlobalException, npFirstChain);
      JclHookExceptions;
    
    finalization
      JclUnhookExceptions;
      JclStopExceptionTracking;
      Lock.Free;
    

    【讨论】:

    • 忘记需要将此添加到您的记录器 JclDebug、JclHookExcept 的用途中
    猜你喜欢
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    • 2017-01-24
    • 2017-06-24
    相关资源
    最近更新 更多