c++中全局变量是先于main函数初始化的而且全局变量的初始化顺序未知,由于这个特点的的原因。全局变量内存别破坏的问题比较难以查找,首先内存被破坏 大部分情况是因为别的变量且这个变量含有指针,出现了内存越界,覆盖了后面变量内存空间,从而使后面的变量被破坏。顺着这个思路我就开始了bug定位之路。
1查看别破坏的全局变量地址对应的内存,发现此变量初始化后是正常值,但是运行到main函数的开头时发现他已经被破坏,说明这个变量应该是被一个全局变量破坏的,从内存的变化来看,应该离此变量不远,先于此变量初始化,于是我就把整个项目的所有全局变量的初始化处打上断点,并没有找到一个符合地址的变量。到这里我意识到这个问题的严重性了,不好找了。
于是我查资料网上说 windbg很强大,其实很早就有耳闻,这次只能请他出山了。最开始下了老版本的windbg发现配置起来太难了,按照教程配置也不行,总是报错说找不到符号文件,我也不知道他说的符号文件到底是我本地的还是微软官方的符号文件,我都疯了,最后查看windows官方文档说官方符号文件的提供方式变了,说不再以http://msdl.microsoft.com/download/symbols这个方式提供符号文件了 改成微软的云服务方式提供,弄的一知半解最后又找了一个新版的windbg 叫windbg preview。直接在win10的应用商店下载就行还是免费的。这个新的windbg preview果然界面友好而且稀里糊涂的就能调试了,好像只需要配置一个环境变量。总之很方便就能跑起我的程序。操作过程如下
首先在命令行输入:bu all_in_rest!g_comManage 这是告诉windbg在g_comManage 处中断,因为我发现g_comManage 这个全局对象在启动之初遭到了破坏所以我先找到它的地址。
接着发现确实能够中断,虽然没有直接跳到对应的代码,然后在memory对象输入&g_comManage找到他的地址
然后呢再输入一个神奇的命令:ba w4 00007FF6`874AF5F0
这个命令的意思是当这个地址四个字节大小的内存如果被写(也就是被破坏)就会中断。继续运行(或者重新调试)发现确实可以捕捉到g_comManage被修改的信息,发现问题出现在我引用的一个dll中改变了这个对象,天啊 没有windbg preview 我什么时候能找到这个问题。
上图 breakpoint 2 就是我打的内存修改断点,看下图。