【问题标题】:Program crashes when outside test environment - C++外部测试环境时程序崩溃 - C++
【发布时间】:2011-09-12 04:05:54
【问题描述】:

我有一个从 Visual Studio 2010 Express 内部运行时运行良好的程序,但是在构建和取出时,它出现了问题。我已经设置了与在 Visual Studio 中运行时相同的外部测试环境,所以这不应该是问题。我想将它附加到 .exe 以查看崩溃的位置,但我没有非 Express 版本。

有什么建议吗?为什么程序在 VSC++ 2010 Express 环境之外会崩溃,但在里面却可以完美运行。

我会发布代码,但这是一个庞大的项目,不会导致错误。

非常感谢您的宝贵时间。

【问题讨论】:

  • 看看这里的回复是否对你有帮助:stackoverflow.com/questions/5905110/…
  • @user791928 它只是说“.exe 已停止工作”然后关闭。
  • @yasouser 这不是一个多线程应用程序,但谢谢。
  • 我应该将我的 Visual Studio 升级到完整版本,然后附加到调试器吗?
  • @Satchmo:你不需要;只需使用 Windows 调试工具。

标签: c++ debugging visual-c++ crash environment


【解决方案1】:

在不知道崩溃是什么的情况下很难确定,但有几个常见问题可能会导致这种情况:

  • 环境变量不一样。也许您在测试环境中依赖于vcvars32.bat 中的某些内容。
  • PATH 环境变量不一样,您选择了一些错误或不兼容的 DLL。
  • 您的代码在某种程度上依赖于当前工作目录,即从 Visual Studio 运行时的工作目录。

【讨论】:

  • 是的,我希望我能提供更多信息,但我真的没有。如果我升级到完整版,我可以将调试器附加到外部 .EXE 并查看导致崩溃的行吗?
  • @satchmo:如果您想节省一些现金并且喜欢冒险,我建议您下载免费的 WinDbg (msdn.microsoft.com/en-us/windows/hardware/gg463009)。它具有调试所需的所有功能,但用户友好性不如 IDE 版本。
【解决方案2】:

Wikipedia to the rescue?

时间也可能是海森虫的一个因素。与正常执行相比,在调试器的控制下执行程序可以改变程序的执行时间。当程序被调试器中的单步源代码行减慢时,可能无法重现时间敏感的错误,例如竞态条件。当行为涉及与不受调试器控制的实体交互时尤其如此,例如在两台机器之间调试网络数据包处理并且只有一台机器处于调试器控制之下时。

另外,请注意User32.dll 略微 在调试器下会改变其行为,以便让您更轻松地进行调试。不过,这不应该改变任何事情。

【讨论】:

  • 我会调查的。也安装完整的 Visual Studio,希望我可以调试。
  • @Satchmo:您听起来太绝望了,无法升级到完整版本的 VS :)。像其他人建议的那样,Windows 调试器工具拥有您需要的一切。如果你有 pdb,你可以像在 VS 的集成调试器中那样单步调试你的代码。
【解决方案3】:

您可以使用免费提供的Debugger Tools for Windows 进行调试。有大量可用的文档和快速入门指南,尤其是安装中包含的 chm。在您的情况下,您可能需要尝试以下方法:

  1. 确保您的应用程序的 PDB 在共享的某处可用。
  2. 附加到应用程序的运行实例:windbg -p <PID>。请注意,您也可以通过 windbg -g foo.exe 在调试器的上下文中启动程序。
  3. 重现崩溃。
  4. 更改符号路径和 Microsoft 公共符号服务器以获得组件的正确符号:.sympath x:\YourPathToPDBs; SRV*x:\symbols*http://msdl.microsoft.com/download/symbols
  5. 告诉调试器使用您的路径重新加载符号:.reload
  6. 在调试器中点击k 获取调用堆栈。

这就是你需要弄清楚它在哪里崩溃的准系统。然后,您可以更深入地尝试通过查看调试器 chm 或 MSDN 或 Tess's blog 上的其他资源来准确分析崩溃的原因。一个有用的命令是dv 转储特定帧的局部变量。如果调用堆栈没有给出行号,请输入.lines,然后点击kkb

【讨论】:

  • 其实你忘了说不需要调试live进程。进程崩溃的 Asp 会生成转储或小型转储文件(取决于 Windows 配置)。您可以在调试器中加载dmp文件并进行分析。
  • @Steve 是的,是的。好评论。我从字面上理解了他的“我想将它附加到.exe”的声明。实时调试的优点是调试器将在异常处停止。然而,根据转储的创建方式,您可能会很幸运,并且在将其加载到调试器中时会在上下文中受到欢迎,或者您需要 .cxr 或通过 ntdll 处理程序检查调用堆栈以找到正确的帧炸毁(或让 !analyze 完成工作)。
【解决方案4】:

您可以用 try catch 块包围 Main 函数中的所有代码。当您捕获异常时,将堆栈跟踪写入日志文件。

然后运行您的 exe 并检查日志文件以了解您的程序崩溃的位置。

PS:不要忘记将*.pdb文件和exe文件放在一起,否则你将无法获取stacktrace信息。

【讨论】:

    【解决方案5】:

    我意识到这个问题已经有几年的历史了,但我一直在经历同样的事情并且遇到了一个可能的罪魁祸首(在我的案例中是真正的罪魁祸首),这可能会帮助遇到这个问题的其他人。

    在 Visual Studio 中运行应用程序和在外部运行应用程序的一个重要区别是当前工作目录(“CWD”)。

    Visual C++ 解决方案/项目的典型目录结构如下:

    Solution     <- the location of your solution file
      Debug      <- where the Debug executables end up
      Release    <- where the Release executables end up
      Project    <- the location of your project file
        Debug    <- where Debug intermediate files end up
        Release  <- where Release intermediate files end up
    

    当您从 Studio 中执行应用程序时,无论是使用“开始调试”还是“开始不调试”,默认 CWD 是项目目录,因此在本例中为 Solution\Project

    但是,当您通过简单地双击应用程序在外部执行时,CWD 是应用程序目录(例如Solution\Debug)。

    如果您尝试从当前目录打开文件(当您执行 std::ifstream ifstr("myfile.txt") 时会发生这种情况),它是否成功取决于您启动应用程序时所处的位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-22
      • 2015-04-04
      • 1970-01-01
      • 1970-01-01
      • 2018-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多