如果你发现你的程序Debug版本好好的,但是Release版本会挂。那么多半你是变量没有初始化或者是内存小规模越界了。
如果你发现你的程序在调试器里好好的,独立运行会挂,那么恭喜你,99%就是变量没有初始化或者是内存越界。
这次老衲犯白痴。两件都碰上了。
上集:
首先的症状就是Release版本在调试器里跑的好好的,一到独立运行就挂了。用debugger attach到crash的进程后发现是c++ exception std::bad_alloc。基本上root cause已经确认。某个地方内存操作越界,把堆给写坏了。导致后续内存分配的时候,分配不到可以用的内存。
但是哪行代码之后的的堆被写坏了呢?邪恶的C++ exception屏蔽了这一信息。经过几个小时的纠结之后,我想起了set_new_handler这样神奇的东西。在crash的模块里设置了new的出错处理代码。
这回,终于能从call stack上看到哪里出错了。
可是,,,我发现这个crash的地方,竟然是随机的。。真是杯具。
折腾了两晚上,把很多不顺眼的代码都修改顺眼了,咦,这回crash的地方竟然是同一个地方了。真是神奇。接下来就简单了。在该位置附近插入一段代码 char* pData = malloc(1024); 很快就确定出问题的起源了:
原先我的TransformBuffer只包含了matWorld matView matProject, 后来shader里有需要用到Camera的信息,于是我就将Camera::Eye(up , pos , dir) 加到了TransformBuffer之后,于是Const Buffer的大小就是 sizeof(xTransMatrixs) + sizeof(Camera::Eye). 过了几天,我又发现,需要把Camera的near/far的信息传递到Shader里去,于是我又加了 near far等四个float到Eye后面,这回我忘记重新调整constant buffer的大小了。杯具就这样产生了。
下集:
搞定了上集的故事后,紧接着我又发现DX11的渲染器里面,Release版本独立运行竟然绘制不出任何东西来。(注:在VC里运行都是好的)。这个似乎比上集的故事更加神奇。我在Model的draw和drawPrimitive里打log,似乎一切都运行的很正常。但是屏幕上就是空空如也,除了改变背景色能起作用意外。其它都没起作用的。
也许是受前几天的影响,这次我学乖了。直接上工具,刚好试了试AMD的GPUPerfStudio,frame debugger一看,每一个多边形都画在正确的位置上.....故障很明显了:Rasterizer或者Blend的状态设置的有问题。注释一下Rasterizer或者Blend的set代码,很快将就确定了:BlendState初始化的时候,没有从xml里去读取SampleMask变量。导致SampleMask错误,FrameBuffer没有写入东西。
这两天的故事就是这样,两个故事的代价我熬了三个晚上。困啊,囧啊。
PS: 2B的AMD和2B 马维尔
2B AMD的profile程序竟然使用80做端口,囧死了。有几个人会在需要远程翻墙的情况下用80来调试的?
2B Marvell,装个Raid驱动程序竟然给我启动了个apache httpd服务。
于是两个2B就这么干上了。