Data race in CreatePlatformShortcuts on gfx::Image refcount |
||||
Issue description
Caught by running InlineInstallPrivateApiTestApp.SuccessfulInstall in browser_tests with TSAN enabled
The issue here is that a gfx::ImageStorage is RefCounted, not RefCountedThreadSafe (and this documented as intentional) however it's being used on one thread while there's a ref being decremented on another.
In practice the caller that binds web_app::internals::CreatePlatformShortcuts() (web_app.cc::ScheduleCreatePlatformShortcut()) is properly careful to std::move() the |shortcut_info| struct containing the gfx::ImageFamily into the callback.
The problem is that gfx::Image and gfx::ImageFamily don't support move-semantics and as such prevent the ref from being moved. Therefore a ref is copied in the callback while another is left behind (to be racily released on the posting thread).
@senorblanco for triage (I think it's just a matter of adding default move-constructors to those two classes)
@tapted: web_app::ShortcutInfo may also need to declare default move-constructors (they're deleted by presence of an explicit destructor...)
Full log:
WARNING: ThreadSanitizer: data race (pid=22073)
Read of size 8 at 0x7b1c0006a3b0 by thread T13:
#0 IsOnValidSequence base/memory/ref_counted.h:118:12 (browser_tests+0x5fe1358)
#1 RepresentationCount ui/gfx/image/image.cc:394 (browser_tests+0x5fe1358)
#2 RepresentationCount ui/gfx/image/image.cc:781 (browser_tests+0x5fe1358)
#3 IsEmpty ui/gfx/image/image.cc:785 (browser_tests+0x5fe1358)
#4 gfx::Image::Width() const ui/gfx/image/image.cc:789 (browser_tests+0x5fe1358)
#5 CreateShortcutIcon chrome/browser/shell_integration_linux.cc:288:21 (browser_tests+0x4725abf)
#6 shell_integration_linux::CreateDesktopShortcut(web_app::ShortcutInfo const&, web_app::ShortcutLocations const&) chrome/browser/shell_integration_linux.cc:957 (browser_tests+0x4725abf)
#7 web_app::internals::CreatePlatformShortcuts(base::FilePath const&, web_app::ShortcutLocations const&, web_app::ShortcutCreationReason, web_app::ShortcutInfo const&) chrome/browser/web_applications/web_app_linux.cc:30:10 (browser_tests+0x472a385)
#8 Invoke<base::FilePath, web_app::ShortcutLocations, web_app::ShortcutCreationReason, const web_app::ShortcutInfo &> base/bind_internal.h:151:12 (browser_tests+0x797c513)
#9 Invoke<base::internal::IgnoreResultHelper<bool (*)(const base::FilePath &, const web_app::ShortcutLocations &, web_app::ShortcutCreationReason, const web_app::ShortcutInfo &)>, base::FilePath, web_app::ShortcutLocations, web_app::ShortcutCreationReason, const web_app::ShortcutInfo &> base/bind_internal.h:224 (browser_tests+0x797c513)
#10 MakeItSo<base::internal::IgnoreResultHelper<bool (*)(const base::FilePath &, const web_app::ShortcutLocations &, web_app::ShortcutCreationReason, const web_app::ShortcutInfo &)>, base::FilePath, web_app::ShortcutLocations, web_app::ShortcutCreationReason, const web_app::ShortcutInfo &> base/bind_internal.h:262 (browser_tests+0x797c513)
#11 RunImpl<base::internal::IgnoreResultHelper<bool (*)(const base::FilePath &, const web_app::ShortcutLocations &, web_app::ShortcutCreationReason, const web_app::ShortcutInfo &)>, std::__1::tuple<base::FilePath, web_app::ShortcutLocations, web_app::ShortcutCreationReason>, 0, 1, 2> base/bind_internal.h:338 (browser_tests+0x797c513)
#12 base::internal::Invoker<base::internal::BindState<base::internal::IgnoreResultHelper<bool (*)(base::FilePath const&, web_app::ShortcutLocations const&, web_app::ShortcutCreationReason, web_app::ShortcutInfo const&)>, base::FilePath, web_app::ShortcutLocations, web_app::ShortcutCreationReason>, void (web_app::ShortcutInfo const&)>::RunOnce(base::internal::BindStateBase*, web_app::ShortcutInfo const&) base/bind_internal.h:303 (browser_tests+0x797c513)
#13 Run base/callback.h:91:12 (browser_tests+0x797c7d5)
#14 Invoke<base::Callback<void (const web_app::ShortcutInfo &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, const web_app::ShortcutInfo &> base/bind_internal.h:241 (browser_tests+0x797c7d5)
#15 MakeItSo<base::Callback<void (const web_app::ShortcutInfo &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, const web_app::ShortcutInfo &> base/bind_internal.h:262 (browser_tests+0x797c7d5)
#16 RunImpl<base::Callback<void (const web_app::ShortcutInfo &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, std::__1::tuple<base::internal::ConstRefWrapper<web_app::ShortcutInfo> >, 0> base/bind_internal.h:338 (browser_tests+0x797c7d5)
#17 base::internal::Invoker<base::internal::BindState<base::Callback<void (web_app::ShortcutInfo const&), (base::internal::CopyMode)0, (base::internal::RepeatMode)0>, base::internal::ConstRefWrapper<web_app::ShortcutInfo> >, void ()>::RunOnce(base::internal::BindStateBase*) base/bind_internal.h:303 (browser_tests+0x797c7d5)
#18 Run base/callback.h:91:12 (browser_tests+0x427292d)
#19 base::(anonymous namespace)::PostTaskAndReplyRelay::RunTaskAndPostReply() base/threading/post_task_and_reply_impl.cc:45 (browser_tests+0x427292d)
#20 Invoke<base::(anonymous namespace)::PostTaskAndReplyRelay *> base/bind_internal.h:196:12 (browser_tests+0x4272c45)
#21 MakeItSo<void (base::(anonymous namespace)::PostTaskAndReplyRelay::*)(), base::(anonymous namespace)::PostTaskAndReplyRelay *> base/bind_internal.h:262 (browser_tests+0x4272c45)
#22 RunImpl<void (base::(anonymous namespace)::PostTaskAndReplyRelay::*)(), std::__1::tuple<base::internal::UnretainedWrapper<base::(anonymous namespace)::PostTaskAndReplyRelay> >, 0> base/bind_internal.h:338 (browser_tests+0x4272c45)
#23 base::internal::Invoker<base::internal::BindState<void (base::(anonymous namespace)::PostTaskAndReplyRelay::*)(), base::internal::UnretainedWrapper<base::(anonymous namespace)::PostTaskAndReplyRelay> >, void ()>::RunOnce(base::internal::BindStateBase*) base/bind_internal.h:303 (browser_tests+0x4272c45)
#24 Run base/callback.h:91:12 (browser_tests+0x41b5b3a)
#25 base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:59 (browser_tests+0x41b5b3a)
#26 base::internal::TaskTracker::PerformRunTask(std::__1::unique_ptr<base::internal::Task, std::__1::default_delete<base::internal::Task> >, base::internal::Sequence*) base/task_scheduler/task_tracker.cc:335:28 (browser_tests+0x4265c89)
#27 base::internal::TaskTrackerPosix::PerformRunTask(std::__1::unique_ptr<base::internal::Task, std::__1::default_delete<base::internal::Task> >, base::internal::Sequence*) base/task_scheduler/task_tracker_posix.cc:22:16 (browser_tests+0x426662a)
#28 base::internal::TaskTracker::RunNextTask(base::internal::Sequence*) base/task_scheduler/task_tracker.cc:251:5 (browser_tests+0x4265113)
#29 base::internal::SchedulerWorker::Thread::ThreadMain() base/task_scheduler/scheduler_worker.cc:84:34 (browser_tests+0x42e85a4)
#30 base::(anonymous namespace)::ThreadFunc(void*) base/threading/platform_thread_posix.cc:71:13 (browser_tests+0x42725a8)
Previous write of size 8 at 0x7b1c0006a3b0 by main thread:
#0 base::subtle::RefCountedBase::Release() const base/memory/ref_counted.h:82:5 (browser_tests+0x762819)
#1 Release base/memory/ref_counted.h:308:33 (browser_tests+0x5fe00c9)
#2 Release base/memory/ref_counted.h:640 (browser_tests+0x5fe00c9)
#3 ~scoped_refptr base/memory/ref_counted.h:535 (browser_tests+0x5fe00c9)
#4 gfx::Image::~Image() ui/gfx/image/image.cc:533 (browser_tests+0x5fe00c9)
#5 ~pair buildtools/third_party/libc++/trunk/include/utility:312:29 (browser_tests+0x5fe302b)
#6 __destroy<std::__1::pair<const gfx::ImageFamily::MapKey, gfx::Image> > buildtools/third_party/libc++/trunk/include/memory:1726 (browser_tests+0x5fe302b)
#7 destroy<std::__1::pair<const gfx::ImageFamily::MapKey, gfx::Image> > buildtools/third_party/libc++/trunk/include/memory:1589 (browser_tests+0x5fe302b)
#8 std::__1::__tree<std::__1::__value_type<gfx::ImageFamily::MapKey, gfx::Image>, std::__1::__map_value_compare<gfx::ImageFamily::MapKey, std::__1::__value_type<gfx::ImageFamily::MapKey, gfx::Image>, std::__1::less<gfx::ImageFamily::MapKey>, true>, std::__1::allocator<std::__1::__value_type<gfx::ImageFamily::MapKey, gfx::Image> > >::destroy(std::__1::__tree_node<std::__1::__value_type<gfx::ImageFamily::MapKey, gfx::Image>, void*>*) buildtools/third_party/libc++/trunk/include/__tree:1831 (browser_tests+0x5fe302b)
#9 ~__tree buildtools/third_party/libc++/trunk/include/__tree:1819:3 (browser_tests+0x5fe2dd6)
#10 ~map buildtools/third_party/libc++/trunk/include/map:805 (browser_tests+0x5fe2dd6)
#11 gfx::ImageFamily::~ImageFamily() ui/gfx/image/image_family.cc:28 (browser_tests+0x5fe2dd6)
#12 extensions::ImageLoader::ReplyBackWithImageFamily(base::Callback<void (gfx::ImageFamily const&), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&) extensions/browser/image_loader.cc:342:1 (browser_tests+0x2ce5425)
#13 Invoke<const base::WeakPtr<extensions::ImageLoader> &, const base::Callback<void (const gfx::ImageFamily &), base::internal::CopyMode::Copyable, base::internal::RepeatMode::Repeating> &, const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &> base/bind_internal.h:196:12 (browser_tests+0x2ce6661)
#14 MakeItSo<void (extensions::ImageLoader::*const &)(const base::Callback<void (const gfx::ImageFamily &), base::internal::CopyMode::Copyable, base::internal::RepeatMode::Repeating> &, const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), const base::WeakPtr<extensions::ImageLoader> &, const base::Callback<void (const gfx::ImageFamily &), base::internal::CopyMode::Copyable, base::internal::RepeatMode::Repeating> &, const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &> base/bind_internal.h:282 (browser_tests+0x2ce6661)
#15 RunImpl<void (extensions::ImageLoader::*const &)(const base::Callback<void (const gfx::ImageFamily &), base::internal::CopyMode::Copyable, base::internal::RepeatMode::Repeating> &, const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), const std::__1::tuple<base::WeakPtr<extensions::ImageLoader>, base::Callback<void (const gfx::ImageFamily &), base::internal::CopyMode::Copyable, base::internal::RepeatMode::Repeating> > &, 0, 1> base/bind_internal.h:338 (browser_tests+0x2ce6661)
#16 base::internal::Invoker<base::internal::BindState<void (extensions::ImageLoader::*)(base::Callback<void (gfx::ImageFamily const&), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&), base::WeakPtr<extensions::ImageLoader>, base::Callback<void (gfx::ImageFamily const&), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> >, void (std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&)>::Run(base::internal::BindStateBase*, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&) base/bind_internal.h:316 (browser_tests+0x2ce6661)
#17 Run base/callback.h:91:12 (browser_tests+0x2ce62bd)
#18 void base::internal::ReplyAdapter<std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> >, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&>(base::Callback<void (std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&), (base::internal::CopyMode)0, (base::internal::RepeatMode)0>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> >*) base/post_task_and_reply_with_result_internal.h:27 (browser_tests+0x2ce62bd)
#19 Invoke<base::Callback<void (const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > *> base/bind_internal.h:151:12 (browser_tests+0x2ce63db)
#20 MakeItSo<void (*)(base::Callback<void (const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > *), base::Callback<void (const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > *> base/bind_internal.h:262 (browser_tests+0x2ce63db)
#21 RunImpl<void (*)(base::Callback<void (const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > *), std::__1::tuple<base::Callback<void (const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, base::internal::OwnedWrapper<std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > > >, 0, 1> base/bind_internal.h:338 (browser_tests+0x2ce63db)
#22 base::internal::Invoker<base::internal::BindState<void (*)(base::Callback<void (std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&), (base::internal::CopyMode)0, (base::internal::RepeatMode)0>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> >*), base::Callback<void (std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&), (base::internal::CopyMode)0, (base::internal::RepeatMode)0>, base::internal::OwnedWrapper<std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > > >, void ()>::RunOnce(base::internal::BindStateBase*) base/bind_internal.h:303 (browser_tests+0x2ce63db)
#23 Run base/callback.h:91:12 (browser_tests+0x4272b9d)
#24 base::(anonymous namespace)::PostTaskAndReplyRelay::RunReplyAndSelfDestruct() base/threading/post_task_and_reply_impl.cc:60 (browser_tests+0x4272b9d)
#25 Invoke<base::(anonymous namespace)::PostTaskAndReplyRelay *> base/bind_internal.h:196:12 (browser_tests+0x4272c45)
#26 MakeItSo<void (base::(anonymous namespace)::PostTaskAndReplyRelay::*)(), base::(anonymous namespace)::PostTaskAndReplyRelay *> base/bind_internal.h:262 (browser_tests+0x4272c45)
#27 RunImpl<void (base::(anonymous namespace)::PostTaskAndReplyRelay::*)(), std::__1::tuple<base::internal::UnretainedWrapper<base::(anonymous namespace)::PostTaskAndReplyRelay> >, 0> base/bind_internal.h:338 (browser_tests+0x4272c45)
#28 base::internal::Invoker<base::internal::BindState<void (base::(anonymous namespace)::PostTaskAndReplyRelay::*)(), base::internal::UnretainedWrapper<base::(anonymous namespace)::PostTaskAndReplyRelay> >, void ()>::RunOnce(base::internal::BindStateBase*) base/bind_internal.h:303 (browser_tests+0x4272c45)
#29 Run base/callback.h:91:12 (browser_tests+0x41b5b3a)
#30 base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:59 (browser_tests+0x41b5b3a)
#31 base::MessageLoop::RunTask(base::PendingTask*) base/message_loop/message_loop.cc:422:19 (browser_tests+0x41ed9bf)
#32 base::MessageLoop::DeferOrRunPendingTask(base::PendingTask) base/message_loop/message_loop.cc:433:5 (browser_tests+0x41edeab)
#33 base::MessageLoop::DoWork() base/message_loop/message_loop.cc:540:13 (browser_tests+0x41ee35b)
#34 base::MessagePumpGlib::Run(base::MessagePump::Delegate*) base/message_loop/message_pump_glib.cc:313:49 (browser_tests+0x41f280b)
#35 base::MessageLoop::Run() base/message_loop/message_loop.cc:369:10 (browser_tests+0x41ed333)
#36 non-virtual thunk to base::MessageLoop::Run() base/message_loop/message_loop.cc (browser_tests+0x41ed37d)
#37 base::RunLoop::Run() base/run_loop.cc:112:14 (browser_tests+0x4235ed4)
#38 RunThisRunLoop content/public/test/test_utils.cc:130:13 (browser_tests+0x4d39959)
#39 content::RunMessageLoop() content/public/test/test_utils.cc:124 (browser_tests+0x4d39959)
#40 ExtensionTestMessageListener::WaitUntilSatisfied() extensions/test/extension_test_message_listener.cc:50:3 (browser_tests+0xb50853e)
#41 extensions::InlineInstallPrivateApiTestBase::Run(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) chrome/browser/extensions/api/inline_install_private/inline_install_private_apitest.cc:34:5 (browser_tests+0x12e455b)
#42 RunTestOnMainThread chrome/browser/extensions/api/inline_install_private/inline_install_private_apitest.cc:49:3 (browser_tests+0x12e4724)
#43 virtual thunk to extensions::InlineInstallPrivateApiTestApp_SuccessfulInstall_Test::RunTestOnMainThread() chrome/browser/extensions/api/inline_install_private/inline_install_private_apitest.cc (browser_tests+0x12e4724)
#44 content::BrowserTestBase::ProxyRunTestOnMainThreadLoop() content/public/test/browser_test_base.cc:315:5 (browser_tests+0x4cd5e0e)
#45 Invoke<content::BrowserTestBase *> base/bind_internal.h:196:12 (browser_tests+0x4cd6fd5)
#46 MakeItSo<void (content::BrowserTestBase::*const &)(), content::BrowserTestBase *> base/bind_internal.h:262 (browser_tests+0x4cd6fd5)
#47 RunImpl<void (content::BrowserTestBase::*const &)(), const std::__1::tuple<base::internal::UnretainedWrapper<content::BrowserTestBase> > &, 0> base/bind_internal.h:338 (browser_tests+0x4cd6fd5)
#48 base::internal::Invoker<base::internal::BindState<void (content::BrowserTestBase::*)(), base::internal::UnretainedWrapper<content::BrowserTestBase> >, void ()>::Run(base::internal::BindStateBase*) base/bind_internal.h:316 (browser_tests+0x4cd6fd5)
#49 Run base/callback.h:80:12 (browser_tests+0x495326a)
#50 ChromeBrowserMainParts::PreMainMessageLoopRunImpl() chrome/browser/chrome_browser_main.cc:1908 (browser_tests+0x495326a)
#51 ChromeBrowserMainParts::PreMainMessageLoopRun() chrome/browser/chrome_browser_main.cc:1261:18 (browser_tests+0x4951abf)
#52 content::BrowserMainLoop::PreMainMessageLoopRun() content/browser/browser_main_loop.cc:1153:13 (browser_tests+0x2345e50)
#53 Invoke<content::BrowserMainLoop *> base/bind_internal.h:196:12 (browser_tests+0x2349795)
#54 MakeItSo<int (content::BrowserMainLoop::*const &)(), content::BrowserMainLoop *> base/bind_internal.h:262 (browser_tests+0x2349795)
#55 RunImpl<int (content::BrowserMainLoop::*const &)(), const std::__1::tuple<base::internal::UnretainedWrapper<content::BrowserMainLoop> > &, 0> base/bind_internal.h:338 (browser_tests+0x2349795)
#56 base::internal::Invoker<base::internal::BindState<int (content::BrowserMainLoop::*)(), base::internal::UnretainedWrapper<content::BrowserMainLoop> >, int ()>::Run(base::internal::BindStateBase*) base/bind_internal.h:316 (browser_tests+0x2349795)
#57 Run base/callback.h:80:12 (browser_tests+0x29f8f4e)
#58 content::StartupTaskRunner::RunAllTasksNow() content/browser/startup_task_runner.cc:45 (browser_tests+0x29f8f4e)
#59 content::BrowserMainLoop::CreateStartupTasks() content/browser/browser_main_loop.cc:936:25 (browser_tests+0x234398b)
#60 content::BrowserMainRunnerImpl::Initialize(content::MainFunctionParams const&) content/browser/browser_main_runner.cc:127:17 (browser_tests+0x234a145)
#61 content::BrowserMain(content::MainFunctionParams const&) content/browser/browser_main.cc:42:32 (browser_tests+0x23401a0)
#62 content::RunNamedProcessTypeMain(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, content::MainFunctionParams const&, content::ContentMainDelegate*) content/app/content_main_runner.cc:408:14 (browser_tests+0x4177da4)
#63 content::ContentMainRunnerImpl::Run() content/app/content_main_runner.cc:687:12 (browser_tests+0x4178af7)
#64 content::ContentServiceManagerMainDelegate::RunEmbedderProcess() content/app/content_service_manager_main_delegate.cc:51:32 (browser_tests+0x41765af)
#65 service_manager::Main(service_manager::MainParams const&) services/service_manager/embedder/main.cc:469:29 (browser_tests+0x6fc686a)
#66 content::ContentMain(content::ContentMainParams const&) content/app/content_main.cc:19:10 (browser_tests+0x4176d4b)
#67 content::BrowserTestBase::SetUp() content/public/test/browser_test_base.cc:271:3 (browser_tests+0x4cd5996)
#68 InProcessBrowserTest::SetUp() chrome/test/base/in_process_browser_test.cc:271:20 (browser_tests+0x4318920)
#69 SetUp chrome/browser/extensions/extension_browsertest.cc:164:25 (browser_tests+0x1475aa4)
#70 virtual thunk to ExtensionBrowserTest::SetUp() chrome/browser/extensions/extension_browsertest.cc (browser_tests+0x1475aa4)
#71 HandleExceptionsInMethodIfSupported<testing::Test, void> third_party/googletest/src/googletest/src/gtest.cc:2455:12 (browser_tests+0x18d88b6)
#72 testing::Test::Run() third_party/googletest/src/googletest/src/gtest.cc:2467 (browser_tests+0x18d88b6)
#73 testing::TestInfo::Run() third_party/googletest/src/googletest/src/gtest.cc:2653:11 (browser_tests+0x18d98ad)
#74 testing::TestCase::Run() third_party/googletest/src/googletest/src/gtest.cc:2771:28 (browser_tests+0x18da0e6)
#75 testing::internal::UnitTestImpl::RunAllTests() third_party/googletest/src/googletest/src/gtest.cc:4648:43 (browser_tests+0x18e3426)
#76 HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> third_party/googletest/src/googletest/src/gtest.cc:2455:12 (browser_tests+0x18e2e24)
#77 testing::UnitTest::Run() third_party/googletest/src/googletest/src/gtest.cc:4256 (browser_tests+0x18e2e24)
#78 RUN_ALL_TESTS third_party/googletest/src/googletest/include/gtest/gtest.h:2237:46 (browser_tests+0x4333b75)
#79 base::TestSuite::Run() base/test/test_suite.cc:270 (browser_tests+0x4333b75)
#80 ChromeTestSuiteRunner::RunTestSuite(int, char**) chrome/test/base/chrome_test_launcher.cc:68:38 (browser_tests+0x419f538)
#81 ChromeTestLauncherDelegate::RunTestSuite(int, char**) chrome/test/base/chrome_test_launcher.cc:77:19 (browser_tests+0x419f65f)
#82 content::LaunchTests(content::TestLauncherDelegate*, unsigned long, int, char**) content/public/test/test_launcher.cc:520:31 (browser_tests+0x4d32224)
#83 LaunchChromeTests(unsigned long, content::TestLauncherDelegate*, int, char**) chrome/test/base/chrome_test_launcher.cc:149:10 (browser_tests+0x419fac0)
#84 main chrome/test/base/browser_tests_main.cc:21:10 (browser_tests+0x419f3fa)
Location is heap block of size 112 at 0x7b1c0006a3b0 allocated by main thread:
#0 operator new(unsigned long) <null> (browser_tests+0x5f2129)
#1 gfx::Image::Image(gfx::ImageSkia const&) ui/gfx/image/image.cc:498:16 (browser_tests+0x5fdfe0a)
#2 gfx::ImageFamily::Add(gfx::ImageSkia const&) ui/gfx/image/image_family.cc:42:7 (browser_tests+0x5fe2fb7)
#3 extensions::ImageLoader::ReplyBackWithImageFamily(base::Callback<void (gfx::ImageFamily const&), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&) extensions/browser/image_loader.cc:338:18 (browser_tests+0x2ce5356)
#4 Invoke<const base::WeakPtr<extensions::ImageLoader> &, const base::Callback<void (const gfx::ImageFamily &), base::internal::CopyMode::Copyable, base::internal::RepeatMode::Repeating> &, const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &> base/bind_internal.h:196:12 (browser_tests+0x2ce6661)
#5 MakeItSo<void (extensions::ImageLoader::*const &)(const base::Callback<void (const gfx::ImageFamily &), base::internal::CopyMode::Copyable, base::internal::RepeatMode::Repeating> &, const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), const base::WeakPtr<extensions::ImageLoader> &, const base::Callback<void (const gfx::ImageFamily &), base::internal::CopyMode::Copyable, base::internal::RepeatMode::Repeating> &, const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &> base/bind_internal.h:282 (browser_tests+0x2ce6661)
#6 RunImpl<void (extensions::ImageLoader::*const &)(const base::Callback<void (const gfx::ImageFamily &), base::internal::CopyMode::Copyable, base::internal::RepeatMode::Repeating> &, const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), const std::__1::tuple<base::WeakPtr<extensions::ImageLoader>, base::Callback<void (const gfx::ImageFamily &), base::internal::CopyMode::Copyable, base::internal::RepeatMode::Repeating> > &, 0, 1> base/bind_internal.h:338 (browser_tests+0x2ce6661)
#7 base::internal::Invoker<base::internal::BindState<void (extensions::ImageLoader::*)(base::Callback<void (gfx::ImageFamily const&), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> const&, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&), base::WeakPtr<extensions::ImageLoader>, base::Callback<void (gfx::ImageFamily const&), (base::internal::CopyMode)1, (base::internal::RepeatMode)1> >, void (std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&)>::Run(base::internal::BindStateBase*, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&) base/bind_internal.h:316 (browser_tests+0x2ce6661)
#8 Run base/callback.h:91:12 (browser_tests+0x2ce62bd)
#9 void base::internal::ReplyAdapter<std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> >, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&>(base::Callback<void (std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&), (base::internal::CopyMode)0, (base::internal::RepeatMode)0>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> >*) base/post_task_and_reply_with_result_internal.h:27 (browser_tests+0x2ce62bd)
#10 Invoke<base::Callback<void (const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > *> base/bind_internal.h:151:12 (browser_tests+0x2ce63db)
#11 MakeItSo<void (*)(base::Callback<void (const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > *), base::Callback<void (const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > *> base/bind_internal.h:262 (browser_tests+0x2ce63db)
#12 RunImpl<void (*)(base::Callback<void (const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > *), std::__1::tuple<base::Callback<void (const std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > &), base::internal::CopyMode::MoveOnly, base::internal::RepeatMode::Once>, base::internal::OwnedWrapper<std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > > >, 0, 1> base/bind_internal.h:338 (browser_tests+0x2ce63db)
#13 base::internal::Invoker<base::internal::BindState<void (*)(base::Callback<void (std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&), (base::internal::CopyMode)0, (base::internal::RepeatMode)0>, std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> >*), base::Callback<void (std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > const&), (base::internal::CopyMode)0, (base::internal::RepeatMode)0>, base::internal::OwnedWrapper<std::__1::vector<extensions::ImageLoader::LoadResult, std::__1::allocator<extensions::ImageLoader::LoadResult> > > >, void ()>::RunOnce(base::internal::BindStateBase*) base/bind_internal.h:303 (browser_tests+0x2ce63db)
#14 Run base/callback.h:91:12 (browser_tests+0x4272b9d)
#15 base::(anonymous namespace)::PostTaskAndReplyRelay::RunReplyAndSelfDestruct() base/threading/post_task_and_reply_impl.cc:60 (browser_tests+0x4272b9d)
#16 Invoke<base::(anonymous namespace)::PostTaskAndReplyRelay *> base/bind_internal.h:196:12 (browser_tests+0x4272c45)
#17 MakeItSo<void (base::(anonymous namespace)::PostTaskAndReplyRelay::*)(), base::(anonymous namespace)::PostTaskAndReplyRelay *> base/bind_internal.h:262 (browser_tests+0x4272c45)
#18 RunImpl<void (base::(anonymous namespace)::PostTaskAndReplyRelay::*)(), std::__1::tuple<base::internal::UnretainedWrapper<base::(anonymous namespace)::PostTaskAndReplyRelay> >, 0> base/bind_internal.h:338 (browser_tests+0x4272c45)
#19 base::internal::Invoker<base::internal::BindState<void (base::(anonymous namespace)::PostTaskAndReplyRelay::*)(), base::internal::UnretainedWrapper<base::(anonymous namespace)::PostTaskAndReplyRelay> >, void ()>::RunOnce(base::internal::BindStateBase*) base/bind_internal.h:303 (browser_tests+0x4272c45)
#20 Run base/callback.h:91:12 (browser_tests+0x41b5b3a)
#21 base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:59 (browser_tests+0x41b5b3a)
#22 base::MessageLoop::RunTask(base::PendingTask*) base/message_loop/message_loop.cc:422:19 (browser_tests+0x41ed9bf)
#23 base::MessageLoop::DeferOrRunPendingTask(base::PendingTask) base/message_loop/message_loop.cc:433:5 (browser_tests+0x41edeab)
#24 base::MessageLoop::DoWork() base/message_loop/message_loop.cc:540:13 (browser_tests+0x41ee35b)
#25 base::MessagePumpGlib::Run(base::MessagePump::Delegate*) base/message_loop/message_pump_glib.cc:313:49 (browser_tests+0x41f280b)
#26 base::MessageLoop::Run() base/message_loop/message_loop.cc:369:10 (browser_tests+0x41ed333)
#27 non-virtual thunk to base::MessageLoop::Run() base/message_loop/message_loop.cc (browser_tests+0x41ed37d)
#28 base::RunLoop::Run() base/run_loop.cc:112:14 (browser_tests+0x4235ed4)
#29 RunThisRunLoop content/public/test/test_utils.cc:130:13 (browser_tests+0x4d39959)
#30 content::RunMessageLoop() content/public/test/test_utils.cc:124 (browser_tests+0x4d39959)
#31 ExtensionTestMessageListener::WaitUntilSatisfied() extensions/test/extension_test_message_listener.cc:50:3 (browser_tests+0xb50853e)
#32 extensions::InlineInstallPrivateApiTestBase::Run(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) chrome/browser/extensions/api/inline_install_private/inline_install_private_apitest.cc:34:5 (browser_tests+0x12e455b)
#33 RunTestOnMainThread chrome/browser/extensions/api/inline_install_private/inline_install_private_apitest.cc:49:3 (browser_tests+0x12e4724)
#34 virtual thunk to extensions::InlineInstallPrivateApiTestApp_SuccessfulInstall_Test::RunTestOnMainThread() chrome/browser/extensions/api/inline_install_private/inline_install_private_apitest.cc (browser_tests+0x12e4724)
#35 content::BrowserTestBase::ProxyRunTestOnMainThreadLoop() content/public/test/browser_test_base.cc:315:5 (browser_tests+0x4cd5e0e)
#36 Invoke<content::BrowserTestBase *> base/bind_internal.h:196:12 (browser_tests+0x4cd6fd5)
#37 MakeItSo<void (content::BrowserTestBase::*const &)(), content::BrowserTestBase *> base/bind_internal.h:262 (browser_tests+0x4cd6fd5)
#38 RunImpl<void (content::BrowserTestBase::*const &)(), const std::__1::tuple<base::internal::UnretainedWrapper<content::BrowserTestBase> > &, 0> base/bind_internal.h:338 (browser_tests+0x4cd6fd5)
#39 base::internal::Invoker<base::internal::BindState<void (content::BrowserTestBase::*)(), base::internal::UnretainedWrapper<content::BrowserTestBase> >, void ()>::Run(base::internal::BindStateBase*) base/bind_internal.h:316 (browser_tests+0x4cd6fd5)
#40 Run base/callback.h:80:12 (browser_tests+0x495326a)
#41 ChromeBrowserMainParts::PreMainMessageLoopRunImpl() chrome/browser/chrome_browser_main.cc:1908 (browser_tests+0x495326a)
#42 ChromeBrowserMainParts::PreMainMessageLoopRun() chrome/browser/chrome_browser_main.cc:1261:18 (browser_tests+0x4951abf)
#43 content::BrowserMainLoop::PreMainMessageLoopRun() content/browser/browser_main_loop.cc:1153:13 (browser_tests+0x2345e50)
#44 Invoke<content::BrowserMainLoop *> base/bind_internal.h:196:12 (browser_tests+0x2349795)
#45 MakeItSo<int (content::BrowserMainLoop::*const &)(), content::BrowserMainLoop *> base/bind_internal.h:262 (browser_tests+0x2349795)
#46 RunImpl<int (content::BrowserMainLoop::*const &)(), const std::__1::tuple<base::internal::UnretainedWrapper<content::BrowserMainLoop> > &, 0> base/bind_internal.h:338 (browser_tests+0x2349795)
#47 base::internal::Invoker<base::internal::BindState<int (content::BrowserMainLoop::*)(), base::internal::UnretainedWrapper<content::BrowserMainLoop> >, int ()>::Run(base::internal::BindStateBase*) base/bind_internal.h:316 (browser_tests+0x2349795)
#48 Run base/callback.h:80:12 (browser_tests+0x29f8f4e)
#49 content::StartupTaskRunner::RunAllTasksNow() content/browser/startup_task_runner.cc:45 (browser_tests+0x29f8f4e)
#50 content::BrowserMainLoop::CreateStartupTasks() content/browser/browser_main_loop.cc:936:25 (browser_tests+0x234398b)
#51 content::BrowserMainRunnerImpl::Initialize(content::MainFunctionParams const&) content/browser/browser_main_runner.cc:127:17 (browser_tests+0x234a145)
#52 content::BrowserMain(content::MainFunctionParams const&) content/browser/browser_main.cc:42:32 (browser_tests+0x23401a0)
#53 content::RunNamedProcessTypeMain(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, content::MainFunctionParams const&, content::ContentMainDelegate*) content/app/content_main_runner.cc:408:14 (browser_tests+0x4177da4)
#54 content::ContentMainRunnerImpl::Run() content/app/content_main_runner.cc:687:12 (browser_tests+0x4178af7)
#55 content::ContentServiceManagerMainDelegate::RunEmbedderProcess() content/app/content_service_manager_main_delegate.cc:51:32 (browser_tests+0x41765af)
#56 service_manager::Main(service_manager::MainParams const&) services/service_manager/embedder/main.cc:469:29 (browser_tests+0x6fc686a)
#57 content::ContentMain(content::ContentMainParams const&) content/app/content_main.cc:19:10 (browser_tests+0x4176d4b)
#58 content::BrowserTestBase::SetUp() content/public/test/browser_test_base.cc:271:3 (browser_tests+0x4cd5996)
#59 InProcessBrowserTest::SetUp() chrome/test/base/in_process_browser_test.cc:271:20 (browser_tests+0x4318920)
#60 SetUp chrome/browser/extensions/extension_browsertest.cc:164:25 (browser_tests+0x1475aa4)
#61 virtual thunk to ExtensionBrowserTest::SetUp() chrome/browser/extensions/extension_browsertest.cc (browser_tests+0x1475aa4)
#62 HandleExceptionsInMethodIfSupported<testing::Test, void> third_party/googletest/src/googletest/src/gtest.cc:2455:12 (browser_tests+0x18d88b6)
#63 testing::Test::Run() third_party/googletest/src/googletest/src/gtest.cc:2467 (browser_tests+0x18d88b6)
#64 testing::TestInfo::Run() third_party/googletest/src/googletest/src/gtest.cc:2653:11 (browser_tests+0x18d98ad)
#65 testing::TestCase::Run() third_party/googletest/src/googletest/src/gtest.cc:2771:28 (browser_tests+0x18da0e6)
#66 testing::internal::UnitTestImpl::RunAllTests() third_party/googletest/src/googletest/src/gtest.cc:4648:43 (browser_tests+0x18e3426)
#67 HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> third_party/googletest/src/googletest/src/gtest.cc:2455:12 (browser_tests+0x18e2e24)
#68 testing::UnitTest::Run() third_party/googletest/src/googletest/src/gtest.cc:4256 (browser_tests+0x18e2e24)
#69 RUN_ALL_TESTS third_party/googletest/src/googletest/include/gtest/gtest.h:2237:46 (browser_tests+0x4333b75)
#70 base::TestSuite::Run() base/test/test_suite.cc:270 (browser_tests+0x4333b75)
#71 ChromeTestSuiteRunner::RunTestSuite(int, char**) chrome/test/base/chrome_test_launcher.cc:68:38 (browser_tests+0x419f538)
#72 ChromeTestLauncherDelegate::RunTestSuite(int, char**) chrome/test/base/chrome_test_launcher.cc:77:19 (browser_tests+0x419f65f)
#73 content::LaunchTests(content::TestLauncherDelegate*, unsigned long, int, char**) content/public/test/test_launcher.cc:520:31 (browser_tests+0x4d32224)
#74 LaunchChromeTests(unsigned long, content::TestLauncherDelegate*, int, char**) chrome/test/base/chrome_test_launcher.cc:149:10 (browser_tests+0x419fac0)
#75 main chrome/test/base/browser_tests_main.cc:21:10 (browser_tests+0x419f3fa)
Thread T13 'TaskSchedulerBa' (tid=22182, running) created by main thread at:
#0 pthread_create <null> (browser_tests+0x58da23)
#1 base::(anonymous namespace)::CreateThread(unsigned long, bool, base::PlatformThread::Delegate*, base::PlatformThreadHandle*, base::ThreadPriority) base/threading/platform_thread_posix.cc:110:13 (browser_tests+0x4271ee6)
#2 base::PlatformThread::CreateWithPriority(unsigned long, base::PlatformThread::Delegate*, base::PlatformThreadHandle*, base::ThreadPriority) base/threading/platform_thread_posix.cc:193:10 (browser_tests+0x4271da5)
#3 Initialize base/task_scheduler/scheduler_worker.cc:144:5 (browser_tests+0x42e81f1)
#4 base::internal::SchedulerWorker::Thread::Create(scoped_refptr<base::internal::SchedulerWorker>) base/task_scheduler/scheduler_worker.cc:31 (browser_tests+0x42e81f1)
#5 base::internal::SchedulerWorker::CreateThread() base/task_scheduler/scheduler_worker.cc:328:15 (browser_tests+0x42e7a1f)
#6 base::internal::SchedulerWorker::Start() base/task_scheduler/scheduler_worker.cc:236:5 (browser_tests+0x42e7976)
#7 base::internal::SchedulerWorkerPoolImpl::Start(base::SchedulerWorkerPoolParams const&) base/task_scheduler/scheduler_worker_pool_impl.cc:265:49 (browser_tests+0x42e9333)
#8 base::internal::TaskSchedulerImpl::Start(base::TaskScheduler::InitParams const&) base/task_scheduler/task_scheduler_impl.cc:80:39 (browser_tests+0x4263c66)
#9 content::BrowserMainLoop::CreateThreads() content/browser/browser_main_loop.cc:989:41 (browser_tests+0x2343c38)
#10 Invoke<content::BrowserMainLoop *> base/bind_internal.h:196:12 (browser_tests+0x2349795)
#11 MakeItSo<int (content::BrowserMainLoop::*const &)(), content::BrowserMainLoop *> base/bind_internal.h:262 (browser_tests+0x2349795)
#12 RunImpl<int (content::BrowserMainLoop::*const &)(), const std::__1::tuple<base::internal::UnretainedWrapper<content::BrowserMainLoop> > &, 0> base/bind_internal.h:338 (browser_tests+0x2349795)
#13 base::internal::Invoker<base::internal::BindState<int (content::BrowserMainLoop::*)(), base::internal::UnretainedWrapper<content::BrowserMainLoop> >, int ()>::Run(base::internal::BindStateBase*) base/bind_internal.h:316 (browser_tests+0x2349795)
#14 Run base/callback.h:80:12 (browser_tests+0x29f8f4e)
#15 content::StartupTaskRunner::RunAllTasksNow() content/browser/startup_task_runner.cc:45 (browser_tests+0x29f8f4e)
#16 content::BrowserMainLoop::CreateStartupTasks() content/browser/browser_main_loop.cc:936:25 (browser_tests+0x234398b)
#17 content::BrowserMainRunnerImpl::Initialize(content::MainFunctionParams const&) content/browser/browser_main_runner.cc:127:17 (browser_tests+0x234a145)
#18 content::BrowserMain(content::MainFunctionParams const&) content/browser/browser_main.cc:42:32 (browser_tests+0x23401a0)
#19 content::RunNamedProcessTypeMain(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, content::MainFunctionParams const&, content::ContentMainDelegate*) content/app/content_main_runner.cc:408:14 (browser_tests+0x4177da4)
#20 content::ContentMainRunnerImpl::Run() content/app/content_main_runner.cc:687:12 (browser_tests+0x4178af7)
#21 content::ContentServiceManagerMainDelegate::RunEmbedderProcess() content/app/content_service_manager_main_delegate.cc:51:32 (browser_tests+0x41765af)
#22 service_manager::Main(service_manager::MainParams const&) services/service_manager/embedder/main.cc:469:29 (browser_tests+0x6fc686a)
#23 content::ContentMain(content::ContentMainParams const&) content/app/content_main.cc:19:10 (browser_tests+0x4176d4b)
#24 content::BrowserTestBase::SetUp() content/public/test/browser_test_base.cc:271:3 (browser_tests+0x4cd5996)
#25 InProcessBrowserTest::SetUp() chrome/test/base/in_process_browser_test.cc:271:20 (browser_tests+0x4318920)
#26 SetUp chrome/browser/extensions/extension_browsertest.cc:164:25 (browser_tests+0x1475aa4)
#27 virtual thunk to ExtensionBrowserTest::SetUp() chrome/browser/extensions/extension_browsertest.cc (browser_tests+0x1475aa4)
#28 HandleExceptionsInMethodIfSupported<testing::Test, void> third_party/googletest/src/googletest/src/gtest.cc:2455:12 (browser_tests+0x18d88b6)
#29 testing::Test::Run() third_party/googletest/src/googletest/src/gtest.cc:2467 (browser_tests+0x18d88b6)
#30 testing::TestInfo::Run() third_party/googletest/src/googletest/src/gtest.cc:2653:11 (browser_tests+0x18d98ad)
#31 testing::TestCase::Run() third_party/googletest/src/googletest/src/gtest.cc:2771:28 (browser_tests+0x18da0e6)
#32 testing::internal::UnitTestImpl::RunAllTests() third_party/googletest/src/googletest/src/gtest.cc:4648:43 (browser_tests+0x18e3426)
#33 HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> third_party/googletest/src/googletest/src/gtest.cc:2455:12 (browser_tests+0x18e2e24)
#34 testing::UnitTest::Run() third_party/googletest/src/googletest/src/gtest.cc:4256 (browser_tests+0x18e2e24)
#35 RUN_ALL_TESTS third_party/googletest/src/googletest/include/gtest/gtest.h:2237:46 (browser_tests+0x4333b75)
#36 base::TestSuite::Run() base/test/test_suite.cc:270 (browser_tests+0x4333b75)
#37 ChromeTestSuiteRunner::RunTestSuite(int, char**) chrome/test/base/chrome_test_launcher.cc:68:38 (browser_tests+0x419f538)
#38 ChromeTestLauncherDelegate::RunTestSuite(int, char**) chrome/test/base/chrome_test_launcher.cc:77:19 (browser_tests+0x419f65f)
#39 content::LaunchTests(content::TestLauncherDelegate*, unsigned long, int, char**) content/public/test/test_launcher.cc:520:31 (browser_tests+0x4d32224)
#40 LaunchChromeTests(unsigned long, content::TestLauncherDelegate*, int, char**) chrome/test/base/chrome_test_launcher.cc:149:10 (browser_tests+0x419fac0)
#41 main chrome/test/base/browser_tests_main.cc:21:10 (browser_tests+0x419f3fa)
SUMMARY: ThreadSanitizer: data race base/memory/ref_counted.h:118:12 in IsOnValidSequence
,
Jul 27 2017
I'll take this: I was actually working on a CL to add move semantics to gfx::Image this week. (No explicit bug; it was part of Issue 600237 .) This doesn't fix thread safety in Image but makes it easier to carefully work around it. CL: https://chromium-review.googlesource.com/588033
,
Jul 27 2017
Cool, thanks! I think you'll need gfx::ImageFamily as well for this issue and potentially web_app::ShortcutInfo since it provides an explicit destructor which I think deletes the implicit move-constructors.
,
Jul 27 2017
Ack. Also I'm confused because it looks like the data race is a recent regression *due to* my adding a thread check in r488929, yet it isn't caught by the thread check, only by TSan. I'd like to briefly investigate why the thread check isn't failing in this instance before fixing it.
,
Jul 27 2017
Actually I think this is an incorrect analysis (that it's caused by non-moveability) though that would be good to fix too. Sadly, I cannot reproduce the TSan error on my local machine (I get a whole bunch of other TSan errors and the test times out --- any tips?). Calling std::move on a ShortcutInfo or ImageFamily *does* increment and decrement the refcount due to the lack of move semantics, but it does so in quick succession and I believe in a thread-safe way (otherwise the sequence checker in RefCounted would be triggered). We should fix this, though, as a matter of performance. The real problem appears to be the way that OnImageLoaded hands off the image to the other thread: it actually has a refcount of 2 at the time that PostIOTask is called. Here's the sequence: UI thread: - CreateShortcuts calls GetShortcutInfoForApp with CreateShortcutsWithInfo as callback. - GetShortcutInfoForApp calls ImageLoader::LoadImageFamilyAsync with OnImageLoaded as callback. - ImageLoader::LoadImageFamilyAsync loads ImageSkias on another thread and calls back to ImageLoader::ReplyBackWithImageFamily on the UI thread. - ImageLoader::ReplyBackWithImageFamily creates a new ImageFamily and populates it. Refcount == 1. It then calls the ImageLoaderImageFamilyCallback (OnImageLoaded), passing the ImageFamily *by const-reference*. Refcount is still 1. - OnImageLoaded copies the image family into the ShortcutInfo. Now Refcount == 2. It calls its ShortcutInfoCallback (CreateShortcutsWithInfo) (std::moving the ShortcutInfo). - CreateShortcutsWithInfo calls ScheduleCreatePlatformShortcut (std::moving the ShortcutInfo). Refcount == 2. - ScheduleCreatePlatformShortcut calls PostIOTask (std::moving the ShortcutInfo). Refcount == 2. At this point, two things happen in parallel: 1. UI thread: The stack unwinds. As we pop past ImageLoader::ReplyBackWithImageFamily, its stack-local ImageFamily is deleted, and the Refcount drops to 1. 2. Task thread: Performs operations on the image, which *used to* (prior to r488929) not care about the refcount, but now they do because the sequence checker checks the refcount. So there is a data race on the refcount itself. The race is *not detected* by base::RefCounted's sequence checker because if the refcount drops to 1 first (which it almost always will do since stack unwinding is faster than starting a new task), it will detach the sequence checker. So the problem here is in ImageLoader: it holds onto a reference to the image throughout the lifetime of its callback, when it could simply std::move the newly created Image/ImageFamily into the callback. This requires an interface change (it currently passes by reference) but I think that's a worthwhile change. (This code all goes back to a time before C++11 and move semantics, though we probably could've used scoped_ptr::Pass() at the time.)
,
Jul 27 2017
Interesting, hadn't realized this other copy you found. But one thing I'm convinced of is that std::moving the ShortcutInfo results in copying the ref because the objects involved aren't moveable and the ref stored inside them therefore won't be moved. So maybe you even get to refcount == 3 or 4. base::RefCounted's sequence check passing doesn't mean there isn't a race, it just means that the race happens to resolve in time (the other thread happens to see the new value in time), but TSAN doesn't care about whether the other thread saw the proper value out of luck, if there isn't a barrier between the two memory accesses, it will (correctly) flag a race. Re. reproducing the TSAN race. I don't know... I'm trying to resolve a slew of TSAN errors when enabling browser_tests on TSAN bots and this one was one of them, it's possible however that in the majority of runs it's still hidden under other races (you can try locally suppressing races irrelevant to you? build/sanitizers/tsan_suppressions.cc)
,
Jul 28 2017
#6: > But one thing I'm convinced of is that std::moving the ShortcutInfo results in > copying the ref because the objects involved aren't moveable and the ref stored > inside them therefore won't be moved. So maybe you even get to refcount == 3 or > 4. FWIW I will be adding move constructor/assign to Image as part of this fix (it's needed for fixing ImageLoader) so this is moot. But I think the ref will get cleaned up when ShortcutInfo is moved. If you call std::move on an Image directly (not having a move constructor), you're right that it's essentially a no-op; it does not reset the Image so results in an additional ref until the original Image goes out of scope. However, we are calling std::move on a unique_ptr (of a ShortcutInfo with an ImageFamily with an Image); that does not actually call ShortcutInfo's copy constructor, it just passes along the pointer to the ShortcutInfo. So if the refcount is 1 at that point, it is safe to do this. (But it is 2 due to the above issue.) > base::RefCounted's sequence check passing doesn't mean there isn't a race Yeah. Most sequence checks *do* catch all data races on that value, but the problem is that RefCounted doesn't account for a case where one ref is held on each thread, and there's a race to Release() it on Thread A and use it on Thread B. > Re. reproducing the TSAN race. I don't know... Do you have a WIP CL where you've fixed/suppressed all those other errors that I can patch in locally, so I can run with the exact same conditions as you are and get the above stacktrace?
,
Jul 28 2017
Re. WIP CL, all I have is : https://chromium-review.googlesource.com/c/585228/ and I sometimes rebase it on incoming fixes but right now it's against ToT and it got this failure.
,
Jul 28 2017
OK thanks --- so you haven't got this stacktrace locally right? At least I can use that CL to run it on try bots.
,
Jul 28 2017
,
Jul 28 2017
@#9: correct.
,
Jul 28 2017
I've build a 3-patch solution: 1. https://chromium-review.googlesource.com/c/588033 (add move semantics). 2. https://chromium-review.googlesource.com/c/590338 (fix ImageFamily loader). -- This should fix the problem. 3. https://chromium-review.googlesource.com/c/590512 (fix Image loader). -- Doesn't directly fix anything but better for consistency. Testing it against TSan on: https://chromium-review.googlesource.com/c/590915/
,
Jul 28 2017
It's fixed! https://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_tsan_rel_ng/builds/126317 (InlineInstallPrivateApiTestApp.SuccessfulInstall is not in the failure set...)
,
Jul 31 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/3d83f26ad153fd480b6e2330a90c5ba37f4dd623 commit 3d83f26ad153fd480b6e2330a90c5ba37f4dd623 Author: Matt Giuca <mgiuca@chromium.org> Date: Mon Jul 31 03:37:23 2017 gfx::Image, ImageFamily: Add and remove copying/moving methods. Image: - Adds move constructor/assignment. Not technically required as Image is cheaply copyable, but this allows more efficient moving without incrementing/decrementing the refcount. Also safer for multi-threaded usage. - Removes SwapRepresentations. Was unused, and superseded by std::move. ImageFamily: - Removes copy constructor/assignment. ImageFamily can be fairly heavyweight, so it's best to move it rather than copying. Also it is heavily used across threads and accidental ImageFamily copying is responsible for data races ( https://crbug.com/749342 ). - Adds Clone method, an explicit copy operator for use if necessary. - Adds move constructor/assignment. This should be used where possible. BUG= 600237 , 749342 Change-Id: I00482c8440d62edb8d9fb216c3de65bf4102d153 Reviewed-on: https://chromium-review.googlesource.com/588033 Reviewed-by: Robert Sesek <rsesek@chromium.org> Reviewed-by: Ben Wells <benwells@chromium.org> Commit-Queue: Matt Giuca <mgiuca@chromium.org> Cr-Commit-Position: refs/heads/master@{#490704} [modify] https://crrev.com/3d83f26ad153fd480b6e2330a90c5ba37f4dd623/chrome/browser/web_applications/web_app.cc [modify] https://crrev.com/3d83f26ad153fd480b6e2330a90c5ba37f4dd623/extensions/browser/image_loader_unittest.cc [modify] https://crrev.com/3d83f26ad153fd480b6e2330a90c5ba37f4dd623/ui/gfx/image/image.cc [modify] https://crrev.com/3d83f26ad153fd480b6e2330a90c5ba37f4dd623/ui/gfx/image/image.h [modify] https://crrev.com/3d83f26ad153fd480b6e2330a90c5ba37f4dd623/ui/gfx/image/image_family.cc [modify] https://crrev.com/3d83f26ad153fd480b6e2330a90c5ba37f4dd623/ui/gfx/image/image_family.h [modify] https://crrev.com/3d83f26ad153fd480b6e2330a90c5ba37f4dd623/ui/gfx/image/image_family_unittest.cc [modify] https://crrev.com/3d83f26ad153fd480b6e2330a90c5ba37f4dd623/ui/gfx/image/image_unittest.cc
,
Jul 31 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/2e48351a4312aff769535a593451dbf382371326 commit 2e48351a4312aff769535a593451dbf382371326 Author: Matt Giuca <mgiuca@chromium.org> Date: Mon Jul 31 04:33:36 2017 ImageLoaderImageFamilyCallback: Take ImageFamily value, not reference. The ImageLoader now std::moves the ImageFamily into the callback, rather than holding onto a reference throughout the duration of the callback. Fixes a data race in ScheduleCreatePlatformShortcut where the ImageFamily could not be safely handed off to the other thread (because the ImageLoader was still holding onto a reference). Bug: 749342 Change-Id: I1452e47c892660e5fd06e27e3a0582240a5cbcec Reviewed-on: https://chromium-review.googlesource.com/590338 Reviewed-by: Ben Wells <benwells@chromium.org> Commit-Queue: Matt Giuca <mgiuca@chromium.org> Cr-Commit-Position: refs/heads/master@{#490708} [modify] https://crrev.com/2e48351a4312aff769535a593451dbf382371326/chrome/browser/extensions/bookmark_app_helper.cc [modify] https://crrev.com/2e48351a4312aff769535a593451dbf382371326/chrome/browser/web_applications/web_app.cc [modify] https://crrev.com/2e48351a4312aff769535a593451dbf382371326/extensions/browser/image_loader.cc [modify] https://crrev.com/2e48351a4312aff769535a593451dbf382371326/extensions/browser/image_loader.h [modify] https://crrev.com/2e48351a4312aff769535a593451dbf382371326/extensions/browser/image_loader_unittest.cc
,
Jul 31 2017
This should be fixed now. Let me know if you still see the failure on TSan.
,
Jul 31 2017
Awesome, thanks! The fix looks good to me, I'll let you know if I see this again despite expectations. |
||||
►
Sign in to add a comment |
||||
Comment 1 by tapted@chromium.org
, Jul 27 2017