【问题标题】:User Breakpoint from nowhere不知从何而来的用户断点
【发布时间】:2008-12-22 02:01:11
【问题描述】:

我正在调试 MS VC++ 6.0 中的一些代码。出于某种原因,在我试图删除一些动态分配的内存的某个时刻,它中断了,我收到一个弹出消息框,上面写着“从代码中调用的用户断点”.. 然后弹出反汇编窗口,我见

*memory address* int      3

奇怪的是,在我调用这样的汇编指令的代码中没有任何地方(我认为 asm int 3 是 x86 的硬件中断命令?)..

这可能是什么原因造成的?

编辑:回答:我的代码是“离开”数组的末尾,但仅在 Visual Studio 调试标记的位置中使用 0xFDFDFDFD,称为 NoMan'sLand 围栏。我认为它也称为 Off一个错误..这个数组与我在发生错误时释放内存的点无关。这使得它更难发现.. :(

【问题讨论】:

  • 只是好奇 - 您是否通过单步汇编指令找出调试堆不喜欢的内容或其他一些工具/技术有帮助?
  • 我查看了这个站点highprogrammer.com/alan/windev/visualstudio.html,它说:0xFDFDFDFD 是一个内存值,MSVC++ 调试器用来指示数组中的边界以检测逐个错误。我检查了我的指针和单步执行中的迭代..
  • 源代码,发现我没有正确绑定我的一个数组。所以我想这只是我需要正确检查我的指针的一种情况:)
  • 仅供参考 - 这是一篇详细介绍调试堆使用的大多数特殊填充值的帖子:stackoverflow.com/questions/370195/…
  • 是的,我相信我上面提供的链接在“有趣”内存值下包含相同的信息.. :) 有人可以关闭这个吗?我没有足够的代表:P

标签: c++ debugging visual-c++ visual-c++-6


【解决方案1】:

您可能在调试堆例程中遇到了发现堆损坏的代码。

当您点击 Int 3 时,调用堆栈是什么样的?

编辑:根据您的 cmets 中的堆栈跟踪,例程 _CrtIsValidHeapPointer() 说被释放的指针是错误的。这是来自 MSVC 的 DBGHEAP.C 源代码的 sn-p:

    /*
     * If this ASSERT fails, a bad pointer has been passed in. It may be
     * totally bogus, or it may have been allocated from another heap.
     * The pointer MUST come from the 'local' heap.
     */
    _ASSERTE(_CrtIsValidHeapPointer(pUserData));

pUserData 将是您要删除的指针的值。

【讨论】:

  • NTDLL! 7c90120e() NTDLL! 7c95d454() NTDLL! 7c96c5cf() NTDLL! 7c9603b0() 内核 32! 7c85f8d7()
  • _CrtIsValidHeapPointer(const void * 0x04880068) line 1697 _free_dbg_lk(void * 0x04880068, int 1) line 1044 + 9 bytes _free_dbg(void * 0x04880068, int 1) line 1001 + * 13 bytes operator delete(void 0x04880068) 第 351 行 + 11 个字节
  • 我认为您需要加载 Windows 系统 DLL 的符号。我认为 MSVC 6 不支持(但我可能错了) - 您可能想要下载 Windows 调试工具并使用 WinDBG 调试器:microsoft.com/whdc/devtools/debugging/installx86.mspx
  • 由于它在 _CrtIsValidHeapPointer() 中中断,您可能会释放一个具有虚假值的指针。
  • 感谢您的链接.. 虚假价值是什么意思?垃圾,比如,指针一开始就没有初始化?我很确定是:(
【解决方案2】:

(我认为 asm int 3 是硬件中断 x86 的命令?

是的。它被称为“硬件断点”。如果您在项目源代码中使用 VS 调试器,它就像一个断点(但在代码中)。从 vs2005 开始,如果您的应用程序在没有任何调试器的情况下启动,应用程序将简单地崩溃,就像它启动了一个非托管异常一样。

在很多公司中,有一个简单的宏用于在代码中添加断点。在某些(困难和罕见的)情况下,这可以替代断言和异常:

#define BREAKPOINT __asm { int 3; }

BREAKPOINT;

见:

所以我建议寻找一些执行此操作的宏或对象,或者它可能出现在您没有代码的模块(dll/lib)中?

【讨论】:

  • 是的,程序中打开了一些 dll/lib,我没有它的源代码。但是我不认为这是原因.. Michael Burr 似乎更有可能.. 无论如何谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多