CEF 在调用特定 DLL 中的函数时崩溃
CEF crashes when calling functions in a particular DLL
我有一个 MSVC 项目,这个项目由多个从可执行文件调用的 DLL 组成。其中一个 DLL 初始化 CEF(Chromium 嵌入式框架),另一个提供一些其他通用功能,我们称它们为 cefDLL 和 generalDLL。电话是这样的:
- 所有调用都是从可执行文件完成的。
- 我调用cefDLL中的函数来初始化CEF。
- 我调用函数第二个generalDLL。
- CEF 内部的某些线程崩溃,并出现 Windows 错误弹出窗口报告 "The application was unable to start correct (0xc0000124). Click OK to close the application."。
- 出现一个 Windows 弹出窗口,声明 Application.exe 已停止工作。
- 即使我在 "has stopped working" 弹出窗口中关闭程序,主线程仍继续 运行ning。
如果我尝试 运行 崩溃程序上的调试器,我得到一个空白 Visual Studio,没有调用堆栈,没有局部变量,什么都没有,甚至没有失败的 DLL 的名称。
如果我从另一个 DLL 调用一个函数,从可执行文件本身调用一个函数,或者 none,代码就可以很好地到达我的无限循环(我正在使用无限循环来停止其余的来自 运行ning 的程序)。
如果我让它保持 运行ning 进入程序的其余部分并且不使用无限循环停止它,则 CEF 中的另外两个线程崩溃,总共三个线程崩溃。这些产生与第一个线程完全相同的错误。我不确定是什么原因造成的,因为我还没有时间研究这个。
即使在 generalDLL 中调用的函数完全不做任何事情,这种情况仍然会发生。如果我的代码是
,我确定是调用它们的行为导致的
initializeCEF();
while (true)
{
}
有效,如果代码是
initializeCEF();
someBlankFunctionInGeneralDLL();
while (true)
{
}
线程崩溃。
CEF 的初始化包括:
//Initialize
CefMainArgs mainArgs;
//Launch Threads
CefExecuteProcess(mainArgs, nullptr, nullptr);
//Settings
CefSettings settings;
settings.pack_loading_disabled = true;
settings.windowless_rendering_enabled = true;
settings.multi_threaded_message_loop = false;
settings.no_sandbox = true;
//Sandbox Info
void *sandboxInfo = nullptr;
//Launch System
CefInitialize(mainArgs, settings, nullptr, sandboxInfo);
有谁知道这可能是由什么引起的?它很容易成为我遇到过的最奇怪的错误之一。
该项目非常庞大,大约有 50,000 行,而且实际上没有任何其他相关部分,所以恐怕我无法提供任何示例。让我知道是否有您认为有助于查看的代码。
你知道CEF是多进程的吧?是否有可能您正在初始化 CEF 的主应用程序无法正确启动多个实例,或者在启动时未将所需的命令行参数传递给包含 CEF 的 DLL?请参阅有关 CEF 应用程序结构的文档:https://bitbucket.org/chromiumembedded/cef/wiki/Architecture#markdown-header-cef3
您可以尝试使用“--single-process”参数启动 CEF 以强制它成为 运行 单进程(尽管非常不推荐使用它,因为他们不在此测试 Chromium配置 - 它只是为了调试)。如果您没有将命令行参数传递给 CEF,那可能就是问题的开始。为此,您可以在派生的 CefApp 中为 OnBeforeCommandLineProcessing() 添加一个处理程序 class,正如 CEF 创建者在此处推荐的那样:http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=12928&p=25732&hilit=main_args#p25717。覆盖最终看起来像这样:
void ServiceCenterApp::OnBeforeCommandLineProcessing(const CefString& process_type,
CefRefPtr<CefCommandLine> command_line) {
if(!command_line->HasSwitch("single-process")) {
command_line->AppendSwitch("single-process");
}
}
但我没有看到您定义 CefApp 派生的 class,那将是 CefInitialize() 的参数。例如,cefclient 示例在其 wWinMain():
// SimpleApp implements application-level callbacks. It will create the first
// browser instance in OnContextInitialized() after CEF has initialized.
CefRefPtr<SimpleApp> app(new SimpleApp);
接着是
// Initialize CEF.
CefInitialize(main_args, settings, app.get(), sandbox_info);
在您告诉 CEF 使用派生应用程序的位置,您可以在此处覆盖您需要的任何处理程序。您可能希望从 simple_app 样本开始进行非常基本的覆盖。
对于调试问题,请尝试附加到所有已启动的进程,假设我是错误的并且多个进程正在正确启动。
我有一个 MSVC 项目,这个项目由多个从可执行文件调用的 DLL 组成。其中一个 DLL 初始化 CEF(Chromium 嵌入式框架),另一个提供一些其他通用功能,我们称它们为 cefDLL 和 generalDLL。电话是这样的:
- 所有调用都是从可执行文件完成的。
- 我调用cefDLL中的函数来初始化CEF。
- 我调用函数第二个generalDLL。
- CEF 内部的某些线程崩溃,并出现 Windows 错误弹出窗口报告 "The application was unable to start correct (0xc0000124). Click OK to close the application."。
- 出现一个 Windows 弹出窗口,声明 Application.exe 已停止工作。
- 即使我在 "has stopped working" 弹出窗口中关闭程序,主线程仍继续 运行ning。
如果我尝试 运行 崩溃程序上的调试器,我得到一个空白 Visual Studio,没有调用堆栈,没有局部变量,什么都没有,甚至没有失败的 DLL 的名称。
如果我从另一个 DLL 调用一个函数,从可执行文件本身调用一个函数,或者 none,代码就可以很好地到达我的无限循环(我正在使用无限循环来停止其余的来自 运行ning 的程序)。
如果我让它保持 运行ning 进入程序的其余部分并且不使用无限循环停止它,则 CEF 中的另外两个线程崩溃,总共三个线程崩溃。这些产生与第一个线程完全相同的错误。我不确定是什么原因造成的,因为我还没有时间研究这个。
即使在 generalDLL 中调用的函数完全不做任何事情,这种情况仍然会发生。如果我的代码是
,我确定是调用它们的行为导致的initializeCEF();
while (true)
{
}
有效,如果代码是
initializeCEF();
someBlankFunctionInGeneralDLL();
while (true)
{
}
线程崩溃。
CEF 的初始化包括:
//Initialize
CefMainArgs mainArgs;
//Launch Threads
CefExecuteProcess(mainArgs, nullptr, nullptr);
//Settings
CefSettings settings;
settings.pack_loading_disabled = true;
settings.windowless_rendering_enabled = true;
settings.multi_threaded_message_loop = false;
settings.no_sandbox = true;
//Sandbox Info
void *sandboxInfo = nullptr;
//Launch System
CefInitialize(mainArgs, settings, nullptr, sandboxInfo);
有谁知道这可能是由什么引起的?它很容易成为我遇到过的最奇怪的错误之一。 该项目非常庞大,大约有 50,000 行,而且实际上没有任何其他相关部分,所以恐怕我无法提供任何示例。让我知道是否有您认为有助于查看的代码。
你知道CEF是多进程的吧?是否有可能您正在初始化 CEF 的主应用程序无法正确启动多个实例,或者在启动时未将所需的命令行参数传递给包含 CEF 的 DLL?请参阅有关 CEF 应用程序结构的文档:https://bitbucket.org/chromiumembedded/cef/wiki/Architecture#markdown-header-cef3
您可以尝试使用“--single-process”参数启动 CEF 以强制它成为 运行 单进程(尽管非常不推荐使用它,因为他们不在此测试 Chromium配置 - 它只是为了调试)。如果您没有将命令行参数传递给 CEF,那可能就是问题的开始。为此,您可以在派生的 CefApp 中为 OnBeforeCommandLineProcessing() 添加一个处理程序 class,正如 CEF 创建者在此处推荐的那样:http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=12928&p=25732&hilit=main_args#p25717。覆盖最终看起来像这样:
void ServiceCenterApp::OnBeforeCommandLineProcessing(const CefString& process_type,
CefRefPtr<CefCommandLine> command_line) {
if(!command_line->HasSwitch("single-process")) {
command_line->AppendSwitch("single-process");
}
}
但我没有看到您定义 CefApp 派生的 class,那将是 CefInitialize() 的参数。例如,cefclient 示例在其 wWinMain():
// SimpleApp implements application-level callbacks. It will create the first
// browser instance in OnContextInitialized() after CEF has initialized.
CefRefPtr<SimpleApp> app(new SimpleApp);
接着是
// Initialize CEF.
CefInitialize(main_args, settings, app.get(), sandbox_info);
在您告诉 CEF 使用派生应用程序的位置,您可以在此处覆盖您需要的任何处理程序。您可能希望从 simple_app 样本开始进行非常基本的覆盖。
对于调试问题,请尝试附加到所有已启动的进程,假设我是错误的并且多个进程正在正确启动。