目前正在测试构建在C ++库之上的C#(。Net 4.5)WPF应用程序(托管,我相信,我没有写它)。由于各种(实际)原因,它在服务器上运行(安装了VS2012,是的,yuck)。
程序连接到相机(通过库)并显示它接收的图像帧。
奇怪的是,我正在获得缓冲区溢出(缓冲区溢出,我能理解)。在垃圾收集期间!
A buffer overrun has occurred in App.exe which has corrupted the program's internal state.
各种其他潜在有用的信息花絮:
unsafe
,我正在做的唯一“深奥”事情就是将位图(从库中)转换为BitmapSource
(如this)。 每次调用堆栈,相同:
vcr110_clr0400.dll!__crt_debugger_hook () Unknown
clr.dll!___raise_securityfailure () Unknown
clr.dll!___report_gsfailure () Unknown
clr.dll!CrawlFrame::SetCurGSCookie(unsigned long *) Unknown
clr.dll!StackFrameIterator::Init(class Thread *,class Frame *,struct _REGDISPLAY *,unsigned int) Unknown
clr.dll!Thread::StackWalkFramesEx(struct _REGDISPLAY *,enum StackWalkAction (*)(class CrawlFrame *,void *),void *,unsigned int,class Frame *) Unknown
clr.dll!Thread::StackWalkFrames(enum StackWalkAction (*)(class CrawlFrame *,void *),void *,unsigned int,class Frame *) Unknown
clr.dll!CNameSpace::GcScanRoots(void (*)(class Object * *,struct ScanContext *,unsigned long),int,int,struct ScanContext *,class GCHeap *) Unknown
clr.dll!WKS::gc_heap::mark_phase(int,int) Unknown
clr.dll!WKS::gc_heap::gc1(void) Unknown
clr.dll!WKS::gc_heap::garbage_collect(int) Unknown
clr.dll!WKS::GCHeap::GarbageCollectGeneration(unsigned int,enum WKS::gc_reason) Unknown
clr.dll!WKS::GCHeap::GarbageCollectTry(int,int,int) Unknown
clr.dll!WKS::GCHeap::GarbageCollect(int,int,int) Unknown
clr.dll!GCInterface::Collect(int,int) Unknown
mscorlib.ni.dll!6dcd33e5() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for mscorlib.ni.dll]
mscorlib.ni.dll!6dcd33e5() Unknown
064afa73() Unknown
clr.dll!MethodTable::FastBox(void * *) Unknown
clr.dll!MethodTable::CallFinalizer(class Object *) Unknown
clr.dll!SVR::CallFinalizer(class Object *) Unknown
clr.dll!SVR::CallFinalizer(class Object *) Unknown
clr.dll!SVR::CallFinalizer(class Object *) Unknown
clr.dll!WKS::GCHeap::FinalizerThreadWorker(void *) Unknown
clr.dll!Thread::DoExtraWorkForFinalizer(void) Unknown
clr.dll!Thread::DoExtraWorkForFinalizer(void) Unknown
clr.dll!Thread::DoExtraWorkForFinalizer(void) Unknown
clr.dll!WKS::GCHeap::FinalizerThreadStart(void *) Unknown
clr.dll!Thread::intermediateThreadProc(void *) Unknown
kernel32.dll!@BaseThreadInitThunk@12 () Unknown
ntdll.dll!___RtlUserThreadStart@8 () Unknown
ntdll.dll!__RtlUserThreadStart@8 () Unknown
答案 0 :(得分:2)
看起来像是对我的记忆腐败;该库可能使用不安全和/或非托管内存或固定内存......或者它可能没有固定正确的内存位,或者过早取消固定它们?
至于:
在VS(调试或发布)中运行会阻止它发生(或者至少延迟它比我准备等待的时间更长)
这是因为调试器创建的进程使用不同的堆(即使您在发布模式下运行);使用这个备用堆是处理随机内存损坏时heisenbugs的一个已知来源(我在这一点上没有找到很多来源;我认为它出现在某个地方的Raymond Chen博客上,但我只发现了this)
编辑:参考找到了!来自MSDN:
调试器创建的进程(也称为生成进程)的行为与调试器未创建的进程略有不同。
调试器创建的进程使用特殊的调试堆,而不是使用标准堆API。您可以使用_NO_DEBUG_HEAP环境变量或-hd命令行选项强制生成的进程使用标准堆而不是调试堆。
我最好的猜测是:C ++库会破坏一些内存。 GC来了,发现堆已损坏,崩溃。 或者:C ++库确实忘记将其用作图像缓冲区的内存固定。 GC来了,移动内存。 C ++库不知道,写入现在无效的指针,导致损坏。 GC再次出现,开始处理现在已损坏的内存,崩溃
答案 1 :(得分:2)
与v2 CLR不同,v4 CLR是在启用Microsoft安全CRT扩展的情况下构建的。其中包括检查,在功能退出时,“堆栈金丝雀”没有被覆盖。由/ GS编译器选项启用。
在以前版本中程序的可能结束将是致命执行引擎异常,由函数尝试返回并且返回地址损坏时引发的访问冲突触发。现在它可以更快地解决问题。更可靠的是,损坏的返回地址可能意外地指向有效代码。接下来会发生什么,如果是这种情况通常是真正不可诊断的。并且可以利用。
但根本原因是相同的,GC堆被破坏了。