程序在调试器中运行时会触发断点,但如果在没有调试器的情况下运行则会起作用

时间:2013-05-10 09:23:19

标签: c++ debugging dll crash

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

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

修改

我在窗口收到以下消息:

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

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

修改

抱歉,我忘了提到它是我正在使用的调试版本而不是发布版本。

4 个答案:

答案 0 :(得分:2)

在尝试了所有内容之后,使用所有排列组合并花费了大量时间在这上面,强有力地改变了函数的逻辑。现在它终于有效了。但是,我仍然在寻找原始问题的答案。

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

答案 1 :(得分:0)

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

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

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

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

答案 2 :(得分:0)

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

至少这就是我遇到问题时所拥有的。

答案 3 :(得分:0)

我显然很晚才参加聚会,但我想我会分享我对这个问题的经验,试图揭开一些亮点。

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

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

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

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运行时异常。

我希望这会有所帮助。