我有一个MSVC项目,该项目由从可执行文件调用的多个DLL组成。其中一个DLL初始化CEF(Chromium Embedded Framework),另一个提供其他一般功能,我们称之为cefDLL和generalDLL。这些电话是这样的:
如果我尝试在崩溃的程序上运行调试器,我得到一个空白的Visual Studio,没有调用堆栈,没有本地,没有,甚至没有失败的DLL的名称。
如果我从另一个DLL调用一个函数,一个来自可执行文件本身的函数或根本没有调用函数,代码就达到我的无限循环就好了(我正在使用一个无限循环来阻止程序的其余部分运行)。
如果我让它继续运行到程序的其余部分并且不用无限循环停止它,CEF中的另外两个线程崩溃总共三个崩溃的线程。这些产生与第一个线程完全相同的错误。我不确定是什么原因引起的,因为我还没有时间研究这个问题。
即使在通用DLL中调用的函数完全不执行任何操作,这仍然会发生。如果我的代码是
,我确信这是调用它们的行为导致这种情况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);
有没有人最清楚这可能是由什么造成的?它很容易成为我遇到过的最奇怪的错误之一。 这个项目是5万左右的巨型项目,并没有任何其他相关部分,所以我不能真正提供任何我担心的例子。如果有一些代码你认为它会有所帮助,请告诉我。
答案 0 :(得分:1)
你知道CEF是多进程的,对吧?初始化CEF的主应用程序是否可能无法正确启动多个实例,或者在启动时未将所需的命令行参数传递给包含CEF的DLL?请参阅此文档,了解CEF应用程序的结构:https://bitbucket.org/chromiumembedded/cef/wiki/Architecture#markdown-header-cef3
您可以尝试使用" - 单一流程"来启动CEF强迫它运行单个进程的论点(尽管不推荐使用它,因为它们不会在此配置中测试Chromium - 它只是用于调试)。如果您没有将命令行参数传递给CEF,这可能是您问题的开始。为此,您可以在CefApp派生类中为OnBeforeCommandLineProcessing()添加处理程序,这是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派生类,这将是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使用派生的App,你可以覆盖你需要的任何处理程序。您可能希望从simple_app示例开始,以获得非常基本的覆盖。
对于调试问题,请尝试附加到启动的所有进程,假设我不正确并且多个进程正在正确启动。