New issue
Advanced search Search tips

Issue 773982 link

Starred by 1 user

Issue metadata

Status: Untriaged
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 3
Type: Bug



Sign in to add a comment

Random DCHECK failure due to nested RunLoop() for IO thread on Windows

Project Member Reported by shimazu@chromium.org, Oct 12 2017

Issue description

In my CL (https://crrev.com/c/712674), I've tried to make a nested RunLoop for unit test like base::RunLoop loop(base::RunLoop::Type::kNestableTasksAllowed). However, one test [1] has been failed due to a DCHECK [2]. 
Probably it was because the test took a bit long time to endure an entry to the disk cache, and a nested RunLoop::Run() hit the DCHECK in MessagePumpForIO::WaitForWork() since the task queue got empty. However, it was hard to figure out because only one test hits the failure, and also I expected that the base::RunLoop should work on IO thread too. 
My suggestion is to skip the DCHECK if it's testing or have clearer warning if we are using nested runloop on the IO thread and it should be prohibited.

[1] https://build.chromium.org/p/tryserver.chromium.win/builders/win7_chromium_rel_ng/builds/15404
[2] https://cs.chromium.org/chromium/src/base/message_loop/message_pump_win.cc?type=cs&sq=package:chromium&l=507

== Copy of the stack trace of failing test [1] == 
[ RUN      ] ServiceWorkerContextRecoveryTest/ServiceWorkerContextRecoveryTest.DeleteAndStartOver/1
[6936:4996:1011/091013.700:7308132:FATAL:message_pump_win.cc(507)] Check failed: 1 == state_->run_depth (1 vs. 2)Cannot nest an IO message loop!
Backtrace:
	base::debug::StackTrace::StackTrace [0x029DB3C7+55]
	base::debug::StackTrace::StackTrace [0x029F111A+10]
	base::MessagePumpForIO::DoRunLoop [0x029F1AB8+232]
	base::MessagePumpWin::Run [0x029F226A+74]
	base::MessageLoop::Run [0x02985D27+103]
	base::RunLoop::Run [0x0297E1C5+117]
	content::CreateProviderHostWithDispatcherHost [0x022A15E0+417]
	content::WriteToDiskCacheWithCustomResponseInfo [0x022A19B3+48]
	content::WriteToDiskCache [0x022A196D+295]
	content::EmbeddedWorkerTestHelper::SimulateWorkerScriptCached [0x0228080C+244]
	content::EmbeddedWorkerTestHelper::OnStartWorker [0x0227FD36+310]
	base::internal::FunctorTraits<void (__thiscall content::EmbeddedWorkerTestHelper::*)(int,__int64,GURL const &,GURL const &,bool,mojo::InterfaceRequest<content::mojom::ServiceWorkerEventDispatcher>,mojo::AssociatedInterfacePtrInfo<content::mojom::EmbeddedW [0x0227B5E0+113]
	base::internal::InvokeHelper<1,void>::MakeItSo<void (__thiscall content::EmbeddedWorkerTestHelper::*)(int,__int64,GURL const &,GURL const &,bool,mojo::InterfaceRequest<content::mojom::ServiceWorkerEventDispatcher>,mojo::AssociatedInterfacePtrInfo<content: [0x0227BA51+58]
	base::internal::Invoker<base::internal::BindState<void (__thiscall content::EmbeddedWorkerTestHelper::*)(int,__int64,GURL const &,GURL const &,bool,mojo::InterfaceRequest<content::mojom::ServiceWorkerEventDispatcher>,mojo::AssociatedInterfacePtrInfo<conte [0x0227BE12+63]
	base::internal::Invoker<base::internal::BindState<void (__thiscall content::EmbeddedWorkerTestHelper::*)(int,__int64,GURL const &,GURL const &,bool,mojo::InterfaceRequest<content::mojom::ServiceWorkerEventDispatcher>,mojo::AssociatedInterfacePtrInfo<conte [0x022802F6+22]
	base::debug::TaskAnnotator::RunTask [0x029EE0CA+346]
	base::internal::IncomingTaskQueue::RunTask [0x029F951B+107]
	base::MessageLoop::RunTask [0x02985FE4+692]
	base::MessageLoop::DeferOrRunPendingTask [0x02984B35+229]
	base::MessageLoop::DoWork [0x02985462+786]
	base::MessagePumpForIO::DoRunLoop [0x029F1ADA+266]
	base::MessagePumpWin::Run [0x029F226A+74]
	base::MessageLoop::Run [0x02985D27+103]
	base::RunLoop::RunUntilIdle [0x0297E2E3+195]
	content::RunAllTasksUntilIdle [0x022828A9+88]
	content::ServiceWorkerContextRecoveryTest_DeleteAndStartOver_Test::TestBody [0x00FCF99D+381]
	testing::internal::HandleExceptionsInMethodIfSupported<testing::TestCase,void> [0x0137F566+32]
	testing::Test::Run [0x01386CA0+93]
	testing::TestCase::Run [0x01386D4C+133]
	testing::internal::UnitTestImpl::RunAllTests [0x013870D5+437]
	testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl,bool> [0x0137F5AA+32]
	testing::UnitTest::Run [0x01386EF5+133]
	base::TestSuite::Run [0x022BAF4B+100]
	base::LaunchUnitTests [0x022B94BB+806]
	base::LaunchUnitTests [0x022B91EA+85]
	main [0x01242B92+103]
	__scrt_common_main_seh [0x03AE275A+248] (f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:283)
	BaseThreadInitThunk [0x753A336A+18]
	RtlInitializeExceptionChain [0x77009902+99]
	RtlInitializeExceptionChain [0x770098D5+54]

 

Comment 1 by gab@chromium.org, Oct 12 2017

I think IO threads can't support nesting well (because the OS controls when we're given control via IOCompletionPorts).

I agree that we should ban nesting at an early stage (i.e. when creating the kNestableTasksAllowed RunLoop -- would require introducing something like bool RunLoop::Delegate::NestableTasksPossible()).

Sign in to add a comment