心理调试请求:垃圾收集过程中的缓冲区溢出(Buffer overrun during Garbage

2019-09-02 05:40发布

目前正在测试一个C#建立在C ++库(管理,我相信,我没有写它)的顶部(.NET 4.5)WPF应用程序。 对于不同的(实际)的原因,它的运行的服务器(安装了VS2012,是的,呸)上。

程序(通过库)钩到相机并显示图像帧,它接收。

什么奇怪的是,我得到缓冲区溢出 (缓冲区溢出我能理解)。 和垃圾收集过程中!

A buffer overrun has occurred in App.exe which has corrupted the program's internal state.

各种其他信息可能有用的花絮:

  • 加大了“吞吐量”使得它迟早会发生(秒而不是分钟)
  • 运行在VS(调试或释放)停止它在所有发生的事情(或者至少是延迟时间比我准备等待)
  • 有没有unsafe在我的C#,唯一的“深奥”的事情,我做的是转换位图(从库)成BitmapSource (像这样 )。
  • 该库被编译为X86,exe文件了。

调用堆栈,同时每一次:

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

Answer 1:

与在V2 CLR,V4的CLR被启用了微软安全CRT扩展建成。 其中包括检查的是,在函数退出时,“叠金丝雀”没有被覆盖。 由/ GS编译器选项启用。

你的程序在以前的版本中可能结束将是一个致命的执行引擎异常,通过访问冲突,将当函数试图返回,返回地址被损坏已经提出触发。 现在抓住了问题越早。 而且更可靠,这已损坏的返回地址可以通过事故点到有效的代码。 接下来会发生什么,如果是这样的话通常是真正undiagnosable。 和利用。

但根本原因是一样的,GC堆得到破坏。



Answer 2:

看起来像一个内存破坏给我; 该库有可能使用不安全的和/或托管内存或固定的内存...也许它不是钉扎正确的内存位,或过早地拔除呢?

至于:

运行在VS(调试或释放)停止它在所有发生的事情(或者至少是延迟时间比我准备等待)

这是因为调试器创建的进程使用不同的堆(即使你是在释放模式运行); 用另一种堆是随机内存损坏问题时heisenbugs的已知源(我还没有找到。但是这一点许多来源,我认为这是对雷蒙陈博客的地方,但我只找到这个 )

编辑:参考找到了! 从MSDN :

调试器创建过程(也称为子进程)的行为比调试器不创建进程略有不同。
而不是使用标准堆API的,处理调试器创建使用特殊的调试堆。 可以强制衍生的过程,通过使用_NO_DEBUG_HEAP环境变量或-HD命令行选项来使用标准堆,而不是在调试堆。

我最好的猜测则是:C ++库腐化一些内存。 在GC来了,发现损坏堆,崩溃。 OR:C ++库不忘记给引脚它使用作为图像缓冲存储器。 在GC来了,移动存储器。 C ++库不知道,写入到现在无效的指针,导致腐败。 该GC自带再次,开始在现在损坏的内存,死机工作



文章来源: Buffer overrun during Garbage Collection: psychic debugging request