C++ 单例模式 和静态变量初始化顺序导致的dll加载失败问题

June 12, 2012 | 0 Minute Read

C++如果有很多静态变量处于不同的文件里面,静态变量的初始化顺序是不确定的。碰到一个bug,就是单例模式 静态变量实例A的构造函数里面去调用 类B的静态函数, B的这个静态函数里面访问了自己的静态成员编码C。结果A初始化实在B的静态变量的前面的,所以程序就crash了。因为是在静态变量的构造函数里面失败的,就只会出来一个对话框提示DLL初始化失败,如果是用loadlibrary的也会提示dll加载不成功的。 好像在类的构造函数里面,很容易碰到这种依赖初始化顺序导致的bug啊。上次才碰到一个类的自己的成员变量的初始化顺序导致的bug。 要注意才行!!! 因为上次也碰到的DLL加载失败的问题,所以就怀疑是类的构造函数里面的问题,直接去搜索“static” 关键字,果然最后找到的就是这个问题。 不过有一点,觉得很不好的是,这种程序的初始化函数CRTstartup里面出错的时候,错误大多在类的构造函数上面,其实是可以定位的,但Windows系统好像自己包这个错误消化掉了,他不通知调试器,也就不能定位到到底是在构造函数的那一行出错了。 如果你非要用调试器去调试,他就断在 其他的ntdll.dll 等里面,一点有用的信息都没有。 其实直接报 指令地址出来给别人,就很容易定位到代码了,不知道Linux平台这种构造函数访问非法地址的错误,是什么样子的,下次试试看。

总结一下:
C++的静态变量的初始化顺序是没法保证的,这个好像说effective c++ 里面有说,自己看一下吧。 C++ 的单例模式,使用静态变量或者指针来做的时候,好像都很容易出现问题的,网上有很多讨论了,搜索看看吧。 像chrome的代码,多线程时,还是使用锁类做的。 C++ DLL记载失败的,好像看到几个都是 类的构造函数的问题,准确的说是静态的变量的初始化的时候调用构造函数的问题,比如构造函数访问违法地址,抛出异常等。 除了这个问题去找static变量总没错。 C++ 这种程序初始化时,静态变量构造函数出错的问题,好像不能使用vc调试器直接定位源码。不知道有什么好的办法不?