不同的动态库在加载同一个静态库时,静态库会将代码编译到不同的动态库中,若静态库中有单例或者静态变量等,则会生成多份副本,则达不到单例的作用,严重者则会出现系统问题,不建议使用静态库。
问题介绍
最近半年,项目里出现多次奇怪的crash
。看crash
堆栈都是进程退出的时候静态变量的销毁core
掉了。从堆栈里看不出来哪里逻辑不对,从代码里也看不出来哪里改坏了这个变量,但是像std::unordered_map
析构时候挂掉这种真是不知道怎么查。只能上asan
去看是不是哪里把这个变量的内存写坏了,然而费时费力也没查出来什么。
最后没办法,二分回滚所有相关提交,最后定位到出问题的那次。可是看代码仍然看不出来哪里有问题,只好在这个提交的所有修改里进行二分注释来测试是否会引发关服core
,最后定位到调用的一个库的一个接口就会引发core
。既然定位到了问题,那我就将代码提前return
,不再调用这个接口验证一下是否解决。WTF
,即使这个函数不被执行到也会出现core
,只有彻底把这个函数的调用注释掉才能彻底解决core
的发生。幸亏这个库是我们自己写的,有源代码,于是对这个函数的源代码进行二分注释,发现这个函数内的一个静态变量被销毁了两次,从而引发了core
。
静态单例
在c++11
里,我们已经被教育了,单例模式直接上static
的这个完美解决方案,保证多线程模式下单例数据只会初始化一次。
//sinleton_lib.h
#pragma once
extern int global_var;
class singleton_test
{
singleton_test();
singleton_test(const singleton_test& other) = delete;
public:
static singleton_test& instance();
~singleton_test();
};
//sinleton_lib.cpp
#include "singleton_lib.h"
#include <iostream>
int global_var = 1314;
singleton_test::singleton_test()
{
std::cout<<"singleton_test create at "<<this<<std::endl;
}
singleton_test::~singleton_test()