在CefExecuteProcess前创建线程导致CEF应用触发SIGTRAP崩溃
CEF应用启用额外线程后触发SIGTRAP崩溃问题
启用仅执行无限循环的sampleThread线程后,CEF应用会因SIGTRAP信号退出,调用栈指向zygote进程的沙箱初始化逻辑。
问题代码
void EmtpyThreadFunc() { // 创建一个无限循环线程以保持进程存活 while (true) { sleep(1000); } } int main(int argc, char* argv[]) { std::string name = "MyTestProject"; //std::thread sampleThread(EmtpyThreadFunc); // 启用此行会导致程序崩溃 // 解析命令行参数 auto commandLine = CefCommandLine::CreateCommandLine(); commandLine->InitFromArgv(argc, argv); // 创建对应类型的ClientApp CefRefPtr<CefApp> app; /* 初始化app的代码已省略 */ CefMainArgs args(argc, argv); // 执行子进程(如果有的话) int exitCode = CefExecuteProcess(args, app, NULL); if (exitCode >= 0) { return exitCode; } // 其余代码 }
崩溃调用栈
Program terminated with signal SIGTRAP, Trace/breakpoint trap. #0 0x00007f207dc82b02 in operator() () at ../../services/service_manager/zygote/zygote_main_linux.cc:161 161 ../../services/service_manager/zygote/zygote_main_linux.cc: No such file or directory. [Current thread is 1 (Thread 0x7f2075d31d80 (LWP 86988))] (gdb) bt #0 0x00007f207dc82b02 in operator() () at ../../services/service_manager/zygote/zygote_main_linux.cc:161 #1 EnterLayerOneSandbox () at ../../services/service_manager/zygote/zygote_main_linux.cc:161 #2 ZygoteMain () at ../../services/service_manager/zygote/zygote_main_linux.cc:222 #3 0x00007f207c06748c in RunZygote () at ../../content/app/content_main_runner_impl.cc:471 #4 0x00007f207c068791 in Run () at ../../content/app/content_main_runner_impl.cc:876 #5 0x00007f207dc8383a in MainRun () at ../../services/service_manager/embedder/main.cc:430 #6 0x00007f207dc83d0e in Main () at ../../services/service_manager/embedder/main.cc:477 #7 0x00007f207c066cf1 in content::ContentMain(content::ContentMainParams const&) () at ../../content/app/content_main.cc:19 #8 0x00007f207c29b7a0 in CefExecuteProcess () at ../../cef/libcef/browser/context.cc:220 #9 0x00007f2079f6b6da in cef_execute_process () at ../../cef/libcef_dll/libcef_dll.cc:78 #10 0x00005602a0a53984 in CefExecuteProcess(CefMainArgs const&, scoped_refptr<CefApp>, void*) ()
环境信息
- 系统:Linux
- CEF版本:81.2.16(121版本也出现几乎相同问题)
- 命令行参数:
--no-sandbox --x=0 --y=0 --width=1281 --height=801 --disable-pinch --disable-web-security --log-severity=disable --ignore-certificate-errors --showDevTools
问题原因与修复方案
原因
CEF的CefExecuteProcess负责处理子进程(如zygote、渲染进程)的启动逻辑,Linux下的沙箱机制要求进程进入沙箱前不能存在额外线程——沙箱初始化时会检查线程数量,非主线程的存在会触发断点陷阱(SIGTRAP)。
修复方法
- 延迟线程创建:将额外线程的创建逻辑放在
CefExecuteProcess之后,因为只有主进程会执行到CefExecuteProcess返回后的代码,子进程会直接退出:int main(int argc, char* argv[]) { std::string name = "MyTestProject"; // 解析命令行参数 auto commandLine = CefCommandLine::CreateCommandLine(); commandLine->InitFromArgv(argc, argv); // 创建对应类型的ClientApp CefRefPtr<CefApp> app; /* 初始化app的代码已省略 */ CefMainArgs args(argc, argv); // 执行子进程(如果有的话) int exitCode = CefExecuteProcess(args, app, NULL); if (exitCode >= 0) { return exitCode; } // 仅主进程会执行到这里,此时创建额外线程 std::thread sampleThread(EmtpyThreadFunc); sampleThread.detach(); // 或根据需求管理线程生命周期 // 其余代码 } - 替换不必要的线程:如果创建线程只是为了保持进程存活,CEF主进程本身会通过消息循环维持存活,无需额外线程。可以调用
CefRunMessageLoop()启动CEF消息循环来替代无限循环线程。
内容的提问来源于stack exchange,提问作者the.cicada.himself
相关产品推荐
相关产品推荐

