我制作了一个非常简单的程序,它可以为我自动执行一些操作。我用 C++ 编写它,它在 Windows 上运行。当从 Codeblocks IDE 内部使用 GDB 对其进行调试时,我突然得到了许多断点。我不知道是什么原因导致这个问题。断点似乎与内存问题有关......因为当我修复检测到的内存泄漏时,断点数量显着减少。

gdb 告诉我的确切内容是:

 Program received signal SIGTRAP, Trace/breakpoint trap.
 In ntdll!TpWaitForAlpcCompletion () (C:\Windows\system32\ntdll.dll)

我在我的程序中多次遇到这种情况。我认为我可能做错了一些事情,尽管程序看起来运行得很好并且完成了我想要它做的事情。谁能告诉我问题是什么,因为我不知道去哪里看?另外,如果这不是问题,那么有人知道如何禁用它,因为这会阻止我到达我自己设置的断点?

提前致谢!

编辑:(添加GDB的where命令的输出):我在哪里可以检查每个函数的作用,以便我可以看到我做错了什么?

#0  0x76fefadd in ntdll!TpWaitForAlpcCompletion () from C:\Windows\system32\ntdll.dll
#1  0x0028e894 in ?? ()
#2  0x76fb272c in ntdll!RtlCreateUserStack () from C:\Windows\system32\ntdll.dll
#3  0x00657fb8 in ?? ()
#4  0x00657fb8 in ?? ()
#5  0x76f4b76a in ntdll!RtlDowncaseUnicodeChar () from C:\Windows\system32\ntdll.dll
#6  0x02070005 in ?? ()
#7  0x00000b10 in ?? ()
#8  0x0028e8dc in ?? ()
#9  0x76ff0b37 in ntdll!TpQueryPoolStackInformation () from C:\Windows\system32\ntdll.dll
#10 0x038b0000 in ?? ()
#11 0x00657fb8 in ?? ()
#12 0x76f4b76a in ntdll!RtlDowncaseUnicodeChar () from C:\Windows\system32\ntdll.dll
#13 0x6e6e9a5e in ?? ()
#14 0x038b0000 in ?? ()
#15 0x038b0000 in ?? ()
#16 0x00000000 in ?? ()
有帮助吗?

解决方案

虽然这个问题现在已经很老了,但以下几点可能会对那些像我一样在搜索后来到这里的人有所帮助:

我刚刚在Win7上测试我在WinXP上开发的应用程序时遇到了这个问题。就我而言,它与 Windows 7 内存管理监控和我的应用程序中的错误内存分配有关。

简而言之,在应用程序代码中,错误分配了一个内存块(而不是使用 GlobalAlloc())并被释放 GlobalFree() (这是错误的,因为系统堆是使用 C 运行时内存池中的指针访问的)。虽然这会导致(在这种情况下非常小)内存泄漏,但在 WinXP 上测试时完全没有注意到,并且整个程序显然运行正确。

现在在Win7上执行时,有一个内存监视功能,称为 容错堆 (FTH) 检测到应用程序的此错误(导致异常):

  • 同时它通过输出一些信息 OutputDebugString() (或者可能 DbgPrint())可以使用简单的方式查看 调试视图 工具,或跟踪应用程序时的任何调试器。因此,在收到信号之前,您可以在消息中看到类似的内容:

    警告:堆[name_of_your.exe]:

    警告:指定给 RtlFreeHeap(006B0000, 006A3698) 的地址无效

  • 并且(在应用程序正在调试的情况下)它输出一个断点,该断点在调试器之外没有任何作用,但其他方面应该有助于指出问题。 该断点由 GDB 显示为 SIGTRAP 信号.

此时你有两种选择:

  • 尝试遍历调用堆栈以查找代码中的错误指令(不幸的是,在这种情况下, bt 或者 where gdb 命令无法显示足够远的内容,无法查看我的代码中堆被错误释放的位置 - 如果有人知道如何从启动模块而不是 ntdll 显示正确的调用堆栈,请告诉我)
  • 尝试继续,因为 FTH 能够在内存中自动修补,以尝试解决您的错误(该自动修补也可以在应用程序的下一次运行时提前发生)

为了在堆问题时不停止,正如 Moshe Levi 所说,您可以设置一个 handle SIGTRAP nostop 在启动应用程序之前在 GDB 提示符下。

简而言之:是的,您的代码中确实存在与内存管理相关的问题,但在某些情况下它可以运行而不会崩溃。但在调试模式下,内核会尝试让您找到问题所在。

其他提示

哇,你把我送回了5年,当我在linux平台上使用gdb时:)

使用以下命令接收SIGTRAP时可以阻止gdb中断:

handle SIGTRAP nostop

但我在这里史蒂夫,请尝试使用WinDbg。它专为Windows而构建。

我建议使用本机Windows调试器WinDBG。这将为符号转换为内核模式时提供更好的堆栈跟踪。

我刚刚使用gt / mingw和Qt Creator一起经历了这次崩溃。

我也有其他问题,包括似乎错误的变量(偏移6个字节)。 就我而言,它结果是一个破坏代码的pragma包。

我有这个:

#pragma pack(1)
typedef struct SomeStruct
{
... // structure
} SomeStruct;

...但是我没有使用pragma pack()调用终止它,结束后返回1的包装并返回默认的字节对齐/打包。添加修复它:

#pragma pack(1)
typedef struct SomeStruct
{
... // structure
} SomeStruct;
#pragma pack() // <<-- with this line the heap corruption problem was stopped
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top