CEF 在调用特定 DLL 中的函数时崩溃

CEF crashes when calling functions in a particular DLL

我有一个 MSVC 项目,这个项目由多个从可执行文件调用的 DLL 组成。其中一个 DLL 初始化 CEF(Chromium 嵌入式框架),另一个提供一些其他通用功能,我们称它们为 cefDLL 和 generalDLL。电话是这样的:

  1. 所有调用都是从可执行文件完成的。
  2. 我调用cefDLL中的函数来初始化CEF。
  3. 我调用函数第二个generalDLL。
  4. CEF 内部的某些线程崩溃,并出现 Windows 错误弹出窗口报告 "The application was unable to start correct (0xc0000124). Click OK to close the application."。
  5. 出现一个 Windows 弹出窗口,声明 Application.exe 已停止工作。
  6. 即使我在 "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 样本开始进行非常基本的覆盖。

对于调试问题,请尝试附加到所有已启动的进程,假设我是错误的并且多个进程正在正确启动。