Chromium定制版中同一进程线程内getBrowserStoreParams111为何重复初始化?
在基于Chromium的定制版本中,Release模式下出现同一进程(PID:21636)、同一线程(线程ID:27808)内getBrowserStoreParams111函数的静态变量store_param被初始化两次的异常,Debug模式运行完全正常。
相关代码
common.h
static int getBrowserStoreParams111(int type);
common.cc
int Common::getBrowserStoreParams111(int type) { static int store_param = [type] { int result = type; std::cout << result << std::endl; { std::ofstream outfile("D:\\timestamp.log", std::ios::app); // 追加模式 if (outfile.is_open()) { auto now = std::chrono::system_clock::now(); auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count(); // 写入日志文件 outfile << "getBrowserStoreParams111getBrowserStoreParams111getBrowserStoreParams111.cc timestamp(ms): " << ms << " common" << "type:" << type << " current thread ID: " << std::this_thread::get_id() << std::endl; outfile.flush(); outfile.close(); } } return result; }(); return store_param; }
base\command_line.cc
std::ofstream outfile1("D:\\timestamp.log", std::ios::app); if (outfile1.is_open()) { auto now = std::chrono::system_clock::now(); DWORD pid = GetCurrentProcessId(); auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count(); outfile1 << "begin command_line.cc timestamp(ms) init: " << ms << " pid:" << pid << " current thread ID: " << std::this_thread::get_id() << "initinit init:" << base::WideToUTF8(cmd_line) << std::endl; outfile1.flush(); outfile1.close(); } std::string strHtml = getBrowserStoreParams(); getBrowserStoreParams111(111); std::ofstream outfile("D:\\timestamp.log", std::ios::app); if (outfile.is_open()) { auto now = std::chrono::system_clock::now(); DWORD pid = GetCurrentProcessId(); auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count(); outfile << "end command_line.cc timestamp(ms): " << ms << " pid:" << pid << std::endl; outfile.flush(); outfile.close(); }
日志输出
begin command_line.cc timestamp(ms) init: 1741772439295 pid:21636 current thread ID: 27808 initinit init:out\Release\chrome.exe --token=abcd
getBrowserStoreParams111getBrowserStoreParams111getBrowserStoreParams111.cc timestamp(ms): 1741772439355 common type: 111 current thread ID: 27808
end command_line.cc timestamp(ms): 1741772439355 pid:21636
begin command_line.cc timestamp(ms) init: 1741772439718 pid:21636 current thread ID: 27808 initinit init:out\Release\chrome.exe --token=abcd
getBrowserStoreParams111getBrowserStoreParams111getBrowserStoreParams111.cc timestamp(ms): 1741772439731 common type: 111 current thread ID: 27808
end command_line.cc timestamp(ms): 1741772439731 pid:21636
日志显示getBrowserStoreParams111函数的静态变量初始化逻辑被执行了两次,且两次都在同一个进程和线程中。
原因分析与解决方案
核心原因
- 文件级静态函数的多实例问题:
common.h中声明的static函数是文件级静态,每个包含该头文件的编译单元都会生成独立的函数实例,每个实例拥有自己的store_param静态变量。如果base\command_line.cc所在模块被多次初始化,或其他编译单元也调用该函数,就会触发多次初始化。 - Release模式编译器优化:Chromium使用的Clang/GCC在Release模式下的激进优化,可能破坏静态变量的初始化原子性,导致同一函数实例的静态变量被重复初始化。
解决方案
- 修正函数声明范围:移除
common.h中函数的static修饰符,改为类的静态成员函数,确保全局只有一个函数实例:
// common.h class Common { public: static int getBrowserStoreParams111(int type); };
- 强制单次初始化:使用
std::call_once确保静态变量只初始化一次,规避编译器优化问题:
int Common::getBrowserStoreParams111(int type) { static std::once_flag init_flag; static int store_param; std::call_once(init_flag, [&](){ store_param = type; std::cout << store_param << std::endl; { std::ofstream outfile("D:\\timestamp.log", std::ios::app); if (outfile.is_open()) { auto now = std::chrono::system_clock::now(); auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count(); outfile << "getBrowserStoreParams111.cc timestamp(ms): " << ms << " common type:" << type << " current thread ID: " << std::this_thread::get_id() << std::endl; outfile.flush(); outfile.close(); } } }); return store_param; }
- 检查模块加载逻辑:确认
base\command_line.cc所在模块是否被Chromium的加载机制重复初始化,排查进程内模块重复加载的可能性。
内容的提问来源于stack exchange,提问作者chuya wang

