【问题标题】:Program triggers a breakpoint when run in debugger but works if run without debugger程序在调试器中运行时触发断点,但在没有调试器的情况下运行
【发布时间】:2013-05-10 09:23:18
【问题描述】:

我创建了一个 dll,它与一个服务器应用程序相连。现在的问题是,如果我从命令提示符运行服务器,那么 dll 将运行良好。但是如果我在visual studio中调试服务器,那么服务器会因为dll而崩溃。然后我彻底调试了它,并知道它在分配内存时崩溃了。我检查了所有可能的事情,内存覆盖,内存泄漏,但一切似乎都很好。

以前有人遇到过此类问题。为什么会这样?我也在互联网上搜索过,但我得到的只是“在发布模式下崩溃而不是在调试模式下”。

编辑:

我在窗口上收到以下消息:

Windows 在 tcas.exe 中触发了一个断点。 这可能是由于堆损坏,这表明 tcas.exe 或其已加载的任何 DLL 中存在错误。 这也可能是由于用户在 tcas.exe 具有焦点时按 F12。 输出窗口可能有更多的诊断信息。

如果我点击继续,那么他们不会有任何问题。

编辑:

抱歉,我忘了说这是我使用的调试版本,而不是发布版本。

【问题讨论】:

  • 如果发生堆损坏,那么当我在命令提示符下运行应用程序时也会发生这种情况。我猜调试时内存放松更多。
  • 不一定 - 可能会发生堆损坏,但由于发布版本中的检查要少得多,您通常不会注意到。调试版本故意注意到一些损坏(无论多么轻微)并为您崩溃。使用调试器查看问题所在。
  • @gbjbaanb:对不起,我忘了说这是我使用的调试版本,而不是发布版本。
  • 当您运行带有调试器的程序时,您也会自动获得调试堆。它通过显示此消息并调用断点来告诉您什么时候搞砸了。没有收到此警告意味着命令提示符解决了您的错误。

标签: c++ debugging dll crash


【解决方案1】:

在尝试了一切,使用了所有的排列组合并花费了我大量的时间之后,我强行改变了函数的逻辑。现在它终于开始工作了。但是,我仍在寻找我原来的问题的答案。

我也不明白的一件事是,我在http://www.debuginfo.com/tips/userbpntdll.html 处读到了与我相同的问题,当我为我的应用程序启用完整的页面堆时,如博客中所述,我的应用程序运行良好。调试时不会崩溃。我首先启用了它,以便我可以获得有关堆损坏的详细信息。我希望这个博客能帮助其他有类似问题的人。

【讨论】:

  • 此类页面中的信息对我帮助很大!谢谢!
【解决方案2】:

您的程序可能存在导致堆损坏的错误。

当您run in the debugger 时,您的程序会使用一个特殊版本的堆来帮助查找这些类型的错误。

当您从命令提示符运行时,您的程序(甚至是调试版本)在查找堆损坏方面并没有(全部)获得相同的帮助。您的程序仍然存在错误,但您只是“幸运”地发现在测试运行中没有发现任何问题。

阅读debug heap 并使用它(在调试器中)查找并修复您的错误。

【讨论】:

    【解决方案3】:

    如果您的代码中有指针,您很可能正在使用其中一个指针访问某个未分配的内存,因此当析构函数运行时,它会使您的程序崩溃。

    至少当问题相同时我就是这样。

    【讨论】:

      【解决方案4】:

      显然我参加聚会很晚了,但我想我会分享我在这个问题上的经验,以试图阐明一些观点。

      我目前正在开发一个包含 Windows API 功能的轻量级窗口库。

      我最顶层的 Window 类的声明包括一个指向 CHAR 数组基地址的指针,该数组表示 WNDCLASSEX 类名和相应窗口的标题。此字符串在堆上分配,并始终在 Window 的构造函数中复制,以避免在销毁 Window 对象时取消注册 NULL 类名。 Window 的析构函数也会在 CHAR 缓冲区上调用 delete[]。

      当我开始实现与一个或多个窗口(或派生类)实例一起使用的独立消息处理函数时,第一次出现问题。循环如下:

      DWORD win_api::BeginQueueingMessages
      (
          Window const *  windowList,
          UINT            length,
          INT             showCommandIndex
      )
      {
          BOOL processMessages    = TRUE;
          BOOL isFirstIteration   = TRUE;
      
          while (processMessages)
          {
              for (UINT i = 0; i < length; ++i)
              {
                  Window  window  = windowList[i];
                  HWND    handle  = window.getHandle();
                  MSG     message = {};
      
                  if (isFirstIteration)
                  {
                      ShowWindow(handle, showCommandIndex);
                      UpdateWindow(handle);
      
                      isFirstIteration = FALSE;
                  }
      
                  if (GetMessage(&message, handle, NULL, NULL))
                  {
                      TranslateMessage(&message);
                      DispatchMessage(&message);
                  }
      
                  else
                  {
                      processMessages = FALSE;
                  }
              }
          }
      
          return 0;
      }
      

      我最终确定了以下代码行是罪魁祸首:

      Window window = windowList[i];
      

      我错误地调用了一个由赋值运算符触发的自动实现的复制构造函数。因此,左侧运算符的内部 CHAR 指针现在指向与 windowList[i] 的成员相同的位置,而无需分配新的堆内存。

      稍后,在程序终止期间,在未初始化的内存块上调用 delete[] 并引发 C 运行时异常。

      我希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-30
        • 1970-01-01
        • 2010-10-18
        相关资源
        最近更新 更多