New issue
Advanced search Search tips

Issue 682652 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Jan 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Bug



Sign in to add a comment

SkASSERT in SetDefaultSkiaFactory hit repeatedly in browser_tests on Win10

Project Member Reported by grt@chromium.org, Jan 19 2017

Issue description

There 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.
 

Comment 1 by grt@chromium.org, Jan 19 2017

Looks 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.
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).
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).
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.
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.
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.

Comment 7 by grt@chromium.org, Jan 19 2017

Fantastic. I see that your CL has a green run on the bot. Thanks for the quick turnaround.
Project Member

Comment 8 by bugdroid1@chromium.org, 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

Status: Fixed (was: Assigned)

Sign in to add a comment