Wine 7.10+运行静态链接sqlite3的C++程序挂起原因咨询
问题复现
测试代码
#include <sqlite3.h> int main(int argc, char**argv) { return 0; } void not_called() { sqlite3_initialize(); }
编译运行命令
$ x86_64-w64-mingw32-g++ -c -g -o augh.o augh.cpp $ x86_64-w64-mingw32-g++ -static -fstack-protector -g -o augh.exe augh.o -lsqlite3 $ wine augh.exe
异常表现
在Fedora 36系统下,搭配mingw64-gcc-c++-11.2.1-5.fc36.x86_64、wine-7.12-1.fc36.x86_64、mingw64-sqlite-static-3.36.0.0-3.fc36.noarch,以及更早的wine-7.10-2.fc36.x86_64版本运行时,程序会先输出wine-staging测试版本提示、MESA-INTEL Haswell Vulkan支持不完整警告、DISPLAY1显示设置写入注册表错误,随后持续输出临界区等待超时日志:
0114:err:sync:RtlpWaitForCriticalSection section 00000002DE99D010 "?" wait timed out in thread 0114, blocked by 0000, retrying (60 sec)
程序无限挂起无法退出。
如果注释掉从未被调用的not_called()函数中的sqlite3_initialize()调用,程序输出上述通用提示与警告后即可正常退出。
对照测试结果
- 在Fedora 35系统下,搭配
mingw64-gcc-c++-11.2.1-3.fc35.x86_64、wine-7.2-1.fc35.x86_64、mingw64-sqlite-static-3.36.0.0-2.fc35.noarch版本,无论代码中是否存在sqlite3_initialize()调用,程序均可正常退出; - 在Fedora 36系统下,若将sqlite3改为动态链接,程序同样可以正常退出。
根本原因
这个异常是两个问题叠加导致的:
- 默认参数下静态编译时,链接器不会主动剔除没被实际调用的代码。哪怕
not_called()从头到尾不会跑,只要它里面引用了sqlite3_initialize(),链接器就会把sqlite3静态库里和初始化、线程锁相关的所有代码都塞进最终的EXE里,其中就包括sqlite3专门给静态链接场景做的自动初始化逻辑——这部分逻辑本来是模拟DLL的DllMain入口,会在程序启动时自动创建线程同步用的临界区对象。 - Fedora 36源里的Wine 7.10及之后版本存在PE加载的逻辑回归:静态链接的EXE启动时,全局构造函数的执行顺序出错,sqlite3的临界区初始化逻辑被提前执行,但这个临界区依赖的底层同步对象还没创建完成,直接导致后台等待线程永远等不到临界区释放,只能反复输出超时日志,程序彻底挂死。
动态链接的时候sqlite3是单独的DLL,完全走Windows标准的DLL加载流程,初始化顺序不会乱,自然碰不到这个bug;Fedora 35带的Wine 7.2没有这个加载顺序的问题,所以不管怎么静态链接都能正常跑。
解决方案
根据自己的编译场景选一个即可:
- 静态链接时加参数让链接器自动清理冗余代码:编译阶段加
-ffunction-sections -fdata-sections,链接阶段加-Wl,--gc-sections,这样所有没被实际调用的函数、数据都会被链接器直接删掉,没用到的not_called()和连带的sqlite3自动初始化逻辑根本不会进入最终EXE,直接从根源解决问题。 - 放弃静态链接,换成动态链接sqlite3:去掉链接参数里的
-static,用mingw源里的动态版sqlite3编译,sqlite3会作为独立DLL被加载,走标准的DLL初始化流程,绕开Wine处理静态PE的bug。 - 手动控制sqlite3的初始化流程:如果必须用静态链接又不想改编译参数,直接在
main函数第一行手动调用sqlite3_initialize(),main返回前调用sqlite3_shutdown(),把sqlite3的初始化、清理逻辑放到正常的代码执行流程里,就不会出现启动阶段全局构造乱序触发临界区操作的问题。 - 降级Wine版本:回退到Fedora 35源对应的Wine 7.2版本,这个版本没有静态PE加载顺序的bug,不会触发挂起。
内容的提问来源于stack exchange,提问作者uckelman
相关产品推荐
相关产品推荐

