SkASSERT in SetDefaultSkiaFactory hit repeatedly in browser_tests on Win10 |
||
Issue descriptionThere are a ton of errors like this on tryserver.chromium.win:win10_chromium_x64_rel_ng: 1032:4124:0118/092747.494:INFO:fontmgr_default_win.cc(18)] e:\b\c\b\win\src\skia\ext\fontmgr_default_win.cc:18: fatal error: "assert(g_default_fontmgr == nullptr)" https://build.chromium.org/p/tryserver.chromium.win/builders/win10_chromium_x64_rel_ng/builds/618/steps/browser_tests%20%28with%20patch%29%20on%20Windows-10-10586/logs/stdio I grabbed this stack from a local repro: (1cd0.4be4): Security check failure or stack buffer overrun - code c0000409 (!!! second chance !!!) *** WARNING: Unable to verify checksum for browser_tests.exe browser_tests!abort+0x34: 00007ff6`fd2ca4c0 cd29 int 29h 5:098> k # Child-SP RetAddr Call Site 00 000000e7`c82feb70 00007ff6`fa8f7269 browser_tests!abort+0x34 [d:\rs1\minkernel\crts\ucrt\src\appcrt\startup\abort.cpp @ 77] 01 000000e7`c82feba0 00007ff6`fa6ba85b browser_tests!FX_OutOfMemoryTerminate+0x9 02 000000e7`c82febd0 00007ff6`fbe4159f browser_tests!SetDefaultSkiaFactory+0x4b 03 000000e7`c82fec20 00007ff6`f9b3f724 browser_tests!content::InitializeDWriteFontProxy+0x167 04 000000e7`c82fed90 00007ff6`f9c804d1 browser_tests!content::PpapiPluginMain+0x240 05 000000e7`c82ff0f0 00007ff6`f9c8036d browser_tests!content::RunNamedProcessTypeMain+0x109 06 000000e7`c82ff240 00007ff6`f9c7f5e8 browser_tests!content::ContentMainRunnerImpl::Run+0x16d 07 000000e7`c82ff3d0 00007ff6`fa2c0099 browser_tests!content::ContentMain+0x30 08 000000e7`c82ff400 00007ff6`fd2fcbd9 browser_tests!content::LaunchTests+0x295 09 000000e7`c82ff9d0 00007ff6`fd2fc75f browser_tests!LaunchChromeTests+0x109 0a 000000e7`c82ffa60 00007ff6`fd2b9091 browser_tests!main+0x53 0b (Inline Function) --------`-------- browser_tests!invoke_main+0x22 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 64] 0c 000000e7`c82ffaa0 00007ffb`ad0b8364 browser_tests!__scrt_common_main_seh+0x11d [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 253] 0d 000000e7`c82ffae0 00007ffb`ad7770d1 KERNEL32!BaseThreadInitThunk+0x14 0e 000000e7`c82ffb10 00000000`00000000 ntdll!RtlUserThreadStart+0x21 bungeman@: it looks like you added this assert in r442926. Would you please investigate? Thanks.
,
Jan 19 2017
Not sure what you mean in #1, this is a raw pointer with static storage (due to being in a namespace) and is therefore implicitly nullptr. The issue here appears to be that it is actually being set more than once (which is probably useless, I'll have to check).
,
Jan 19 2017
Interesting, this didn't happen at all at https://luci-logdog.appspot.com/v/?s=chromium%2Fbb%2Ftryserver.chromium.win%2Fwin_chromium_x64_rel_ng%2F346135%2F%2B%2Frecipes%2Fsteps%2Fbrowser_tests__with_patch_%2F0%2Fstdout when my change landed. It appears that this only happens on win10_chromium_x64_rel_ng but not win_chromium_x64_rel_ng, what is different about that bot? I believe the assert here probably is catching an actual issue, this is really lazy initialization of what is effectively a static global which needs to be finished before the first call to the getter (the SkFontMgr::Factory method). If it actually does need to be set more than once then the code needs to change to handle that properly (if this was happening before, it really was leaking).
,
Jan 19 2017
Interesting, so from what I can tell ui/gfx/win/direct_write.cc#MaybeInitializeDirectWrite is getting called first and calling SetDefaultSkiaFactory. Then later content/child/dwrite_font_proxy/dwrite_font_proxy_init_win.cc#InitializeDWriteFontProxy is called which also calls SetDefaultSkiaFactory with a different SkFontMgr, which will lead to a leak, which is what the assert is catching. The reason why this is happening on Win10 and not Win7 appears to be that the latter call is only made if the IDWriteFactory is actually an IDWriteFactory2, which is only available on Win8.1 and later. I'm not sure why this is the case.
,
Jan 19 2017
Actually, I misread the IDWriteFactory2 code. It is not the IDWriteFactory2 test in InitializeDWriteFontProxy causing the difference. It appears that ppapi_plugin_main.cc is doing this to itself. It conditionally calls MaybeInitializeDirectWrite first and then calls InitializeDWriteFontProxy unconditionally. if (!base::win::IsUser32AndGdi32Available()) gfx::win::MaybeInitializeDirectWrite(); InitializeDWriteFontProxy(); IsUser32AndGdi32Available is always true in Win7 (they can't be disabled until Win8) so on Win7 just InitializeDWriteFontProxy is called. On Win8 and later they will both be called, and both of them try to set the global.
,
Jan 19 2017
Something of a work-around at https://codereview.chromium.org/2644103003/ . ppapi code should be updated not to need this since it's effectively creating two SkFontMgr objects and always throwing the first one away on Win8+. However, it's not clear what the right approach is and it's easy to work around for now.
,
Jan 19 2017
Fantastic. I see that your CL has a green run on the bot. Thanks for the quick turnaround.
,
Jan 19 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/5ecd69eb2b90a83d67cce615e564dcc70a2d14bb commit 5ecd69eb2b90a83d67cce615e564dcc70a2d14bb Author: bungeman <bungeman@chromium.org> Date: Thu Jan 19 22:28:42 2017 Allow multiple calls to SetDefaultSkiaFactory on Windows. The ppapi code currently calls SetDefaultSkiaFactory twice on Win8+. Previous code simply leaked an SkFontMgr and the current code asserts (which is how this was discovered). This CL allows SetDefaultSkiaFactory to be called more than once, properly handling the reference counting and asserting in debug builds that SetDefaultSkiaFactory is not called after SkFontMgr::Factory is called. BUG= chromium:682652 Review-Url: https://codereview.chromium.org/2644103003 Cr-Commit-Position: refs/heads/master@{#444865} [modify] https://crrev.com/5ecd69eb2b90a83d67cce615e564dcc70a2d14bb/skia/ext/fontmgr_default_android.cc [modify] https://crrev.com/5ecd69eb2b90a83d67cce615e564dcc70a2d14bb/skia/ext/fontmgr_default_win.cc
,
Jan 19 2017
|
||
►
Sign in to add a comment |
||
Comment 1 by grt@chromium.org
, Jan 19 2017Looks like it's likely just an uninitialized var: namespace { // This is a leaky bare owning pointer. SkFontMgr* g_default_fontmgr; } // namespace I will try to send up a CL if I have time. Feel free to beat me to it.