我知道操作系统有时会使用某些模式(如0xCD和0xDD)初始化内存.我想知道的是何时以及为什么会发生这种情况.
这是否特定于编译器使用?
对于这个,malloc/new和free/delete的工作方式是否相同?
它是特定于平台的吗?
它会出现在其他操作系统上,例如Linux或VxWorks吗?
我的理解是这只发生在Win32调试配置中,它用于检测内存溢出并帮助编译器捕获异常.
你能举一个关于这个初始化如何有用的实际例子吗?
我记得读过一些东西(可能在Code Complete 2中),在分配内存时将内存初始化为已知模式是好的,某些模式会触发Win32中的中断,这将导致调试器中出现异常.
这有多便携?
我这里有一个"Schroedinger's Cat"类型的问题 - 我的程序(实际上是我的程序的测试套件,但是程序仍然是)崩溃,但只有在发布模式下构建时才会发生,并且只有在从命令行启动时.通过穴居人调试(即整个地方讨厌的printf()消息),我已经确定了代码崩溃的测试方法,但遗憾的是实际的崩溃似乎发生在某些析构函数中,因为我看到的最后一条跟踪消息都在其他执行干净的析构函数.
当我尝试在Visual Studio中运行此程序时,它不会崩溃.从WinDbg.exe启动时也是如此.仅从命令行启动时才会发生崩溃.这是在Windows Vista,btw下发生的,不幸的是我现在无法访问XP机器进行测试.
这将是非常好的,如果我能得到的Windows打印出堆栈跟踪,或一些其他不是简单地结束,如果它已经退出干净方案.有没有人对如何在这里获得更有意义的信息有任何建议,希望能解决这个问题?
编辑:问题确实是由一个越界数组引起的,我在这篇文章中对此进行了更多描述.感谢大家帮忙找到这个问题!
除非您正在编程操作系统或嵌入式系统的某些部分,否则有任何理由这样做?我可以想象,对于一些特定的类经常重载内存管理函数或引入一个对象池而创建和销毁的类可能会降低开销,但是在全局范围内做这些事情?
另外
我刚刚在重载的删除功能中发现了一个错误 - 内存并不总是被释放.这是一个不那么重要的内存关键应用程序.此外,禁用这些过载会使性能降低约0.5%.
我睡不着!:)
我在Windows上有一个相当大的项目,遇到了一些堆损坏问题.我已阅读所有SO,包括这个好主题:如何调试堆损坏错误?但是没有什么比开箱即用更能帮助我了.Debug CRT和BoundsChecker检测到堆损坏,但地址总是不同的,并且检测点总是远离实际存储器重写.我没有睡到半夜,并制作了以下黑客:
DWORD PageSize = 0;
inline void SetPageSize()
{
if ( !PageSize )
{
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
PageSize = sysInfo.dwPageSize;
}
}
void* operator new (size_t nSize)
{
SetPageSize();
size_t Extra = nSize % PageSize;
nSize = nSize + ( PageSize - Extra );
return Ptr = VirtualAlloc( 0, nSize, MEM_COMMIT, PAGE_READWRITE);
}
void operator delete (void* pPtr)
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(pPtr, &mbi, sizeof(mbi));
// leave pages in reserved state, but free …Run Code Online (Sandbox Code Playgroud) 我有一个小的单线程C++应用程序,使用Visual Studio 2005编译和链接,使用boost(crc,program_options和tokenizer),一小部分STL和各种其他系统头文件.
(它的主要目的是读取.csv并生成自定义二进制.dat和配对的.h声明结构,"解释".dat的格式.)
在调试器外部运行时,该工具正在崩溃(对NULL的访问冲突),仅在发布时.例如,按F5不会导致工具崩溃,Ctrl-F5会崩溃.当我重新连接调试器时,我得到这个堆栈:
ntdll.dll!_RtlAllocateHeap@12() + 0x26916 bytes
csv2bin.exe!malloc(unsigned int size=0x00000014) Line 163 + 0x63 bytes C
csv2bin.exe!operator new(unsigned int size=0x00000014) Line 59 + 0x8 bytes C++
>csv2bin.exe!Record::addField(const char * string=0x0034aac8) Line 62 + 0x7 bytes C++
csv2bin.exe!main(int argc=0x00000007, char * * argv=0x00343998) Line 253 C++
csv2bin.exe!__tmainCRTStartup() Line 327 + 0x12 bytes C
Run Code Online (Sandbox Code Playgroud)
它崩溃的线是一个看似无害的分配:
pField = new NumberField(this, static_cast<NumberFieldInfo*>(pFieldInfo));
Run Code Online (Sandbox Code Playgroud)
...我不相信它已经到达了构造函数,它只是在跳转到构造函数之前分配内存.它在崩溃时也会执行此代码几十次,通常是在一致(但不是非可疑)的位置.
使用/ MTd或/ MDd(调试运行时)进行编译时问题就消失了,使用/ MT或/ MD时会回来.
NULL从堆栈加载,我可以在内存视图中看到它._RtlAllocateHeap @ 12 + 0x26916字节似乎是一个巨大的偏移,就像一个不正确的跳转一样.
我已经尝试_HAS_ITERATOR_DEBUGGING过调试版本,并没有带来任何可疑的东西.
在Record :: addField的开头和结尾删除HeapValidate会在崩溃时显示一个OK堆.
这曾经工作 …
我有一个使用DLL文件的EXE文件,该文件使用另一个DLL文件.出现这种情况:
在DLL文件1中:
class abc
{
static bool FindSubFolders(const std::string & sFolderToCheck,
std::vector< std::string > & vecSubFoldersFound);
}
Run Code Online (Sandbox Code Playgroud)
在DLL文件2中:
void aFunction()
{
std::vector<std::string> folders;
std::string sLocation;
...
abc::FindSubFolders(sLocation, folders)
}
Run Code Online (Sandbox Code Playgroud)
在发布模式下,一切正常.但是在调试模式下,我std::strings在文件夹向量中的一个析构函数中出现断言失败(当文件夹在aFunction结尾处超出范围时):
dbgheap.c : line 1274
/*
* 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));
Run Code Online (Sandbox Code Playgroud)
我假设这是因为内存已经分配在DLL文件1的堆上,但是在DLL文件2中被释放.
评论dbgheap.c似乎非常坚持这是一个问题.
为什么这是一个问题,如果我忽略它似乎工作正常?是否有一种非断言失败的方式来做到这一点?
我有一个目录更改监视器进程,它从一组目录中的文件读取更新.我有另一个进程,对这些目录(测试程序)执行大量文件的小写操作.图大约100个目录,每个目录有10个文件,每秒约有500个文件被修改.
运行一段时间后,目录监视器进程挂起一个fclose()基本上拖尾文件的方法的调用.在这个方法中,我fopen()是文件,检查句柄是否有效,做一些搜索和读取,然后调用fclose().这些读取都由进程中的同一个线程执行.挂起后,线程永远不会进展.
我找不到任何关于为什么fclose()可能死锁而不是返回某种错误代码的好信息.文档确实提到了_fclose_nolock(),但似乎我没有(Visual Studio 2003).
调试和发布版本都会挂起.在调试版本中,我可以看到在返回之前挂起的fclose()调用_free_base().某种调用kernel32.dll => ntdll.dll => KernelBase.dll => ntdll.dll正在旋转.这是来自ntdll.dll的无限循环的程序集:
77CEB83F cmp dword ptr [edi+4Ch],0
77CEB843 lea esi,[ebx-8]
77CEB846 je 77CEB85E
77CEB848 mov eax,dword ptr [edi+50h]
77CEB84B xor dword ptr [esi],eax
77CEB84D mov al,byte ptr [esi+2]
77CEB850 xor al,byte ptr [esi+1]
77CEB853 xor al,byte ptr [esi]
77CEB855 cmp byte ptr [esi+3],al
77CEB858 jne 77D19A0B
77CEB85E mov eax,200h
77CEB863 cmp word ptr [esi],ax
77CEB866 ja …Run Code Online (Sandbox Code Playgroud) 我有一个在调试版本中运行良好的应用程序,但是当我在发布版本中启动它时,我得到了一个
unhandled Exception at 0x0043b134 in myapp.exe: 0xC0000005:
Access violation while reading at position 0x004bd96c
Run Code Online (Sandbox Code Playgroud)
如果我点击"break",它会告诉我没有加载符号,并且无法显示源代码.
在这种情况下我能做些什么来追查问题?
我"Debug assertions failed!"在调试模式下运行程序时遇到此错误.我尝试在Visual C++网站上查看这个错误,但解释对我来说太先进了,他们与我对问题的最佳猜测没有任何相似之处.
我已经完成了我的代码并缩小了发生错误的点.它似乎发生在代码部分,我在计算机移动到程序的下一部分之前手动删除了一大堆堆数组.当我注释掉释放旧堆数组的部分时,程序运行得非常好.
有什么想法在这里发生?我在编程方面的知识仍然相对基础.
谢谢
我正在使用Visual C++ 2008.
更多信息:
断点在此代码块处触发:
void operator delete(
void *pUserData
)
{
_CrtMemBlockHeader * pHead;
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
if (pUserData == NULL)
return;
_mlock(_HEAP_LOCK); /* block other threads */
__TRY
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));//<---- break point triggers
_free_dbg( pUserData, pHead->nBlockUse );
__FINALLY
_munlock(_HEAP_LOCK); /* release other threads */
__END_TRY_FINALLY
return;
}
Run Code Online (Sandbox Code Playgroud)
此代码来自选项卡:dbgdel.cpp
我已经"缩小"导致此问题的代码部分是这样的:
delete [] topQuadanglesPositions; …Run Code Online (Sandbox Code Playgroud) 如何调试mingw构建的二进制文件以检测堆错误?我看到关于这个主题有几个问题,但它们很通用,很难找到适合MinGW的工具.我花了很多时间来寻找解决方案,我希望合并后的主题会有所帮助.
当有人在Visual Studio调试器下运行它时报告库中的错误时,这样的工具就变得必要了,它会因"堆错误"而停止.
当我的应用程序崩溃时,我有以下调用(通过 MSVC210 保存转储功能和 winbdg 使用 k 命令第二次创建):
0012c720 7d684c89 0012c93c 7d656a16 063acab8 ntdll!DbgBreakPoint
0012c728 7d656a16 063acab8 0000035c 035f0000 ntdll!RtlpBreakPointHeap+0x28
0012c93c 7d685892 035f0000 50000161 0000035c ntdll!RtlAllocateHeapSlowly+0x231
0012c9b0 7d65695e 035f0000 50000161 0000035c ntdll!RtlDebugAllocateHeap+0xaf
0012cbcc 7d62ba89 035f0000 40000060 0000035c ntdll!RtlAllocateHeapSlowly+0x41
0012cdfc 10308343 035f0000 40000060 0000035c ntdll!RtlAllocateHeap+0xe9f
0012ce14 1031697c 0000035c c8fa7bd5 0012deb0 MSVCR100D!_heap_alloc_base+0x53
0012ce5c 1031671f 00000338 00000001 00000000 MSVCR100D!_nh_malloc_dbg+0x2dc
0012ce7c 103166cc 00000338 00000000 00000001 MSVCR100D!_nh_malloc_dbg+0x7f
0012cea4 10319c5b 00000338 00000000 00000001 MSVCR100D!_nh_malloc_dbg+0x2c
0012cec4 10307db1 00000338 04f26388 0012cfac MSVCR100D!malloc+0x1b
0012cee0 65302a58 00000338 c8876569 00000070 MSVCR100D!operator new+0x11 …Run Code Online (Sandbox Code Playgroud)