首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >CEF基::ThreadRestrictions::AssertIOAllowed()断言在app退出时失败

CEF基::ThreadRestrictions::AssertIOAllowed()断言在app退出时失败
EN

Stack Overflow用户
提问于 2014-11-20 18:28:04
回答 1查看 1.2K关注 0票数 1

我有一个简单的CEF应用程序的OSX,是基于提供的cefsample应用程序。一个值得注意的变化是,我是以单进程模式(settings.single_process = true)运行的。由于断言失败,我的飞机在出口处坠毁了。奇怪的是,这种崩溃也发生在发布版本中,而不仅仅是调试版本。

有谁(CEF大师)能帮我理解这里的问题吗?堆栈跟踪显示,我正在从一个不允许IO的线程中调用一个“仅限IO”函数。我所做的唯一的IO就是从应用程序包中加载静态html文件。这看起来不应该需要特殊处理。但是,好的,让我们假设它确实要求我按照断言错误中的建议,“将调用调整为base::ThreadRestrictions::SetIOAllowed()”,这是断言错误中的建议--我不知道如何或在哪里这样做。

下面是堆栈跟踪:

代码语言:javascript
运行
复制
[1120/110258:FATAL:thread_restrictions.cc(38)] Function marked as IO-only was called from a thread that disallows IO!  If this thread really should be allowed to make IO calls, adjust the call to base::ThreadRestrictions::SetIOAllowed() in this thread's startup.
0   Chromium Embedded Framework         0x0068b8cf base::debug::StackTrace::StackTrace() + 63
1   Chromium Embedded Framework         0x0068b92b base::debug::StackTrace::StackTrace() + 43
2   Chromium Embedded Framework         0x00719d52 logging::LogMessage::~LogMessage() + 82
3   Chromium Embedded Framework         0x00718a8b logging::LogMessage::~LogMessage() + 43
4   Chromium Embedded Framework         0x00832984 base::ThreadRestrictions::AssertIOAllowed() + 276
5   Chromium Embedded Framework         0x00810100 base::PlatformThread::Join(base::PlatformThreadHandle) + 48
6   Chromium Embedded Framework         0x008263a3 base::Thread::Stop() + 131
7   Chromium Embedded Framework         0x08413d8f content::InProcessRendererThread::~InProcessRendererThread() + 63
8   Chromium Embedded Framework         0x08413e0b content::InProcessRendererThread::~InProcessRendererThread() + 43
9   Chromium Embedded Framework         0x08413e5e content::InProcessRendererThread::~InProcessRendererThread() + 46
10  Chromium Embedded Framework         0x07bab824 base::DefaultDeleter<base::Thread>::operator()(base::Thread*) const + 68
11  Chromium Embedded Framework         0x07bab7aa base::internal::scoped_ptr_impl<base::Thread, base::DefaultDeleter<base::Thread> >::reset(base::Thread*) + 122
12  Chromium Embedded Framework         0x07b93bc9 scoped_ptr<base::Thread, base::DefaultDeleter<base::Thread> >::reset(base::Thread*) + 57
13  Chromium Embedded Framework         0x07b85dc8 content::RenderProcessHostImpl::~RenderProcessHostImpl() + 392
14  Chromium Embedded Framework         0x07b8632b content::RenderProcessHostImpl::~RenderProcessHostImpl() + 43
15  Chromium Embedded Framework         0x07b864be content::RenderProcessHostImpl::~RenderProcessHostImpl() + 46
16  Chromium Embedded Framework         0x00534d88 CefContentRendererClient::RunSingleProcessCleanupOnUIThread() + 872
17  Chromium Embedded Framework         0x00534888 CefContentRendererClient::RunSingleProcessCleanup() + 344
18  Chromium Embedded Framework         0x003d6ab5 CefContext::FinalizeShutdown() + 69
19  Chromium Embedded Framework         0x003d5b26 CefContext::Shutdown() + 694
20  Chromium Embedded Framework         0x003d5750 CefShutdown() + 512
21  Chromium Embedded Framework         0x0027dbe7 cef_shutdown + 39
22  CEFSimpleSample                     0x000c1a37 CefShutdown() + 39
23  CEFSimpleSample                     0x000baefc main + 388
24  libdyld.dylib                       0x96e33701 start + 1
25  ???                                 0x00000003 0x0 + 3

这是我应用程序的一部分。断言在CEFShutdown()方法中失败,这是一个框架方法:

代码语言:javascript
运行
复制
// Entry point function for the browser process.
int main(int argc, char* argv[]) {
    // Provide CEF with command-line arguments.
    CefMainArgs main_args(argc, argv);

    // ClientHandler implements application-level callbacks. It will create the first
    // browser instance in OnContextInitialized() after CEF has initialized.
    CefRefPtr<ClientHandler> app(new ClientHandler);

    // Initialize the AutoRelease pool.
    NSAutoreleasePool* autopool = [[NSAutoreleasePool alloc] init];

    // Initialize the SimpleApplication instance.
    [SimpleApplication sharedApplication];

    // Specify CEF global settings here.
    CefSettings settings;
    settings.single_process = true;

    // Initialize CEF for the browser process.
    CefInitialize(main_args, settings, app.get(), NULL);

    // Create the application delegate.
    NSObject* delegate = [[SimpleAppDelegate alloc] init];
    [delegate performSelectorOnMainThread:@selector(createApplication:)
                               withObject:nil
                            waitUntilDone:NO];

    // Run the CEF message loop. This will block until CefQuitMessageLoop() is
    // called.
    CefRunMessageLoop();

    // Shut down CEF.
    CefShutdown();

    // Release the delegate.
    [delegate release];

    // Release the AutoRelease pool.
    [autopool release];

    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-21 10:41:00

这是CEF的一个已知错误:

https://code.google.com/p/chromiumembedded/issues/detail?id=1182

up通常区分UI线程和IO线程,消息是断言这些线程是混合的。这与你自己的IO无关。

您需要查看堆栈以了解发生了什么。带有命名空间的函数通常属于铬,而全局命名空间中的函数是CEF本身的一部分。而CEF相关的崩溃往往是由于胶水嵌入铬.

负性函数可能是CefContentRendererClient方法的CefContentRendererClient。这个名称意味着它是在UI线程上运行的。

代码语言:javascript
运行
复制
void CefContentRendererClient::RunSingleProcessCleanupOnUIThread() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  // Clean up the single existing RenderProcessHost.
  content::RenderProcessHost* host = NULL;
  content::RenderProcessHost::iterator iterator(
      content::RenderProcessHost::AllHostsIterator());
  if (!iterator.IsAtEnd()) {
    host = iterator.GetCurrentValue();
    host->Cleanup();
    iterator.Advance();
    DCHECK(iterator.IsAtEnd());
  }
  DCHECK(host);

  // Clear the run_renderer_in_process() flag to avoid a DCHECK in the
  // RenderProcessHost destructor.
  content::RenderProcessHost::SetRunRendererInProcess(false);

  // Deletion of the RenderProcessHost object will stop the render thread and
  // result in a call to WillDestroyCurrentMessageLoop.
  // Cleanup() will cause deletion to be posted as a task on the UI thread but
  // this task will only execute when running in multi-threaded message loop
  // mode (because otherwise the UI message loop has already stopped). Therefore
  // we need to explicitly delete the object when not running in this mode.
  if (!CefContext::Get()->settings().multi_threaded_message_loop)
    delete host;
}

崩溃发生在函数的botton上。实际上,multi_threaded_message_loop是假的(multi_threaded_message_loop仅适用于RenderProcessHostImpl ),我们可以跟踪堆栈跟踪到RenderProcessHostImpl析构函数的崩溃。

从代码和评论中应该可以清楚地看到,这是对code的一次相当肮脏的攻击,试图复制Chromium在其他地方所做的事情。实际上,我认为DCHECK (铬断言宏)的解决方案已经过时,因为在这里设置为false的g_run_renderer_in_process_没有在析构函数中签入。

BrowserMainLoop::ShutdownThreadsAndCleanUp()中的以下评论可能提供一个线索:

代码语言:javascript
运行
复制
// Teardown may start in PostMainMessageLoopRun, and during teardown we
// need to be able to perform IO.
base::ThreadRestrictions::SetIOAllowed(true);
BrowserThread::PostTask(
    BrowserThread::IO, FROM_HERE,
    base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed),
             true));

修复方法可以是在调用base::ThreadRestrictions::SetIOAllowed(true);方法中的析构函数之前调用RunSingleProcessCleanupOnUIThread()。不幸的是,为此您将需要重新编译CEF,并且您不能在主函数中调用这个表达式(在调用CefShutdown()之前),因为CEF不公开这些Chromium内部元素。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27046870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档