繁体   English   中英

在调试器中运行时,程序会触发一个断点,但是如果在没有调试器的情况下运行,则程序可以工作

[英]Program triggers a breakpoint when run in debugger but works if run without debugger

我创建了一个dll,并将其与服务器应用程序连接在一起。 现在的问题是,如果我从命令提示符下运行服务器,则dll将运行正常。 但是,如果我在Visual Studio中调试服务器,则服务器将由于dll而崩溃。 然后我对其进行了彻底的调试,并在分配内存时知道它崩溃了。 我检查了可能的问题,内存覆盖,内存泄漏,但是一切似乎都很好。

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

编辑:

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

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

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

编辑:

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

在尝试了所有方法之后,使用所有排列组合并在此上花费了大量时间,然后强行更改了函数的逻辑。 现在终于可以了。 但是,我仍在寻找我的原始问题的答案。

我还不了解的一件事是,我在http://www.debuginfo.com/tips/userbpntdll.html上阅读了与我相同的问题,以及当我为应用程序启用完整的pageheap时,如博客,我的应用程序运行正常。 调试时不会崩溃。 首先,我启用了它,以便获得有关堆损坏的详细信息。 我希望这个博客可以帮助其他遇到类似问题的人。

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

当您在调试器中运行时 ,您的程序将使用特殊版本的堆,旨在帮助查找这些类型的错误。

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

阅读调试堆,并在调试器中使用它来查找和修复错误。

如果代码中有指针,则很可能使用指针之一访问未分配的内存,因此当析构函数运行时,它将使程序崩溃。

至少那是我在问题相同的时候拥有的东西。

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

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

我最顶层的Window类的声明包括一个指向CHAR数组的基地址的指针,该数组既代表WNDCLASSEX类名,又代表相应的窗口标题。 该字符串在堆上分配,并且始终复制到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运行时异常。

我希望这有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM