Closed Bug 757366 Opened 12 years ago Closed 8 years ago

crash in gfxFontUtils::DecodeFontName


(Core :: Graphics: Text, defect)

14 Branch
Not set



Tracking Status
firefox50 --- affected
firefox51 --- affected
firefox52 --- fixed


(Reporter: scoobidiver, Assigned: jfkthame)



(Keywords: crash, Whiteboard: [native-crash][gfx-noted])

Crash Data


(3 files)

There's one crash in 14.0a2: bp-0479ca5c-1b30-4c6b-b859-2b4412120521 and one in 14.0b2.

Signature 	gfxFontUtils::DecodeFontName More Reports Search
UUID	0479ca5c-1b30-4c6b-b859-2b4412120521
Date Processed	2012-05-21 14:49:57
Uptime	6465
Last Crash	1.9 hours before submission
Install Age	1.8 hours since version was first installed.
Install Time	2012-05-21 13:01:39
Product	FennecAndroid
Version	14.0a2
Build ID	20120521042008
Release Channel	aurora
OS	Linux
OS Version	0.0.0 Linux #1 SMP PREEMPT Fri Mar 23 18:16:07 CST 2012 armv7l
Build Architecture	arm
Build Architecture Info	
Crash Reason	SIGBUS
Crash Address	0x0
App Notes 	
AdapterVendorID: cardhu, AdapterDeviceID: Transformer Prime TF201.
AdapterDescription: 'Model: 'Transformer Prime TF201', Product: 'DE_epad', Manufacturer: 'asus', Hardware: 'cardhu''.
asus Transformer Prime TF201
EMCheckCompatibility	True

Frame 	Module 	Signature 	Source
0 	gfxFontUtils::DecodeFontName 	gfx/thebes/gfxFontUtils.cpp:1007
1 	gfxFontUtils::ReadNames 	gfx/thebes/gfxFontUtils.cpp:1882
2 	gfxFontUtils::ReadCanonicalName 	gfx/thebes/gfxFontUtils.cpp:1587
3 	gfxFontUtils::GetFullNameFromTable 	gfx/thebes/gfxFontUtils.cpp:1537
4 	gfxFontUtils::GetFullNameFromSFNT 	gfx/thebes/gfxFontUtils.cpp:1526
5 	gfxUserFontSet::LoadFont 	gfx/thebes/gfxUserFontSet.cpp:669
6 	gfxUserFontSet::OnLoadComplete 	gfx/thebes/gfxUserFontSet.cpp:464
7 	nsFontFaceLoader::OnStreamComplete 	layout/style/nsFontFaceLoader.cpp:245
8 	nsStreamLoader::OnStopRequest 	netwerk/base/src/nsStreamLoader.cpp:127
9 	nsCORSListenerProxy::OnStopRequest 	content/base/src/nsCrossSiteListenerProxy.cpp:642
10 	nsHttpChannel::OnStopRequest 	netwerk/protocol/http/nsHttpChannel.cpp:4495
11 	nsInputStreamPump::OnStateStop 	netwerk/base/src/nsInputStreamPump.cpp:587
12 	nsInputStreamPump::OnInputStreamReady 	netwerk/base/src/nsInputStreamPump.cpp:405
13 	nsInputStreamReadyEvent::Run 	xpcom/io/nsStreamUtils.cpp:114
14 	nsThread::ProcessNextEvent 	xpcom/threads/nsThread.cpp:656
15 	NS_ProcessNextEvent_P 	obj-firefox/xpcom/build/nsThreadUtils.cpp:245
16 	mozilla::ipc::MessagePump::Run 	ipc/glue/MessagePump.cpp:114
17 	MessageLoop::RunInternal 	ipc/chromium/src/base/
18 	MessageLoop::Run 	ipc/chromium/src/base/
19 	nsBaseAppShell::Run 	widget/xpwidgets/nsBaseAppShell.cpp:189
20 	nsAppStartup::Run 	toolkit/components/startup/nsAppStartup.cpp:295
21 	XREMain::XRE_mainRun 	toolkit/xre/nsAppRunner.cpp:3780
22 	XREMain::XRE_main 	toolkit/xre/nsAppRunner.cpp:3857
23 	XRE_main 	toolkit/xre/nsAppRunner.cpp:3933

More reports at:
Got simmilar crash in x86_64 using Gentoo, GCC-4.9.0
Got the same issue with nightly 37 (backtrace, build config and version in the attached file).
Btw, one of the websites that cause firefox to crash is
Mmmh, turns out that what seems to cause the error is when I build firefox with GCC 4.9 and -O3 flag.
Also happens with gcc-5:

Program received signal SIGSEGV, Segmentation fault.
0x00007fffeee4089c in gfxFontUtils::DecodeFontName(char const*, int, unsigned int, unsigned int, unsigned int, nsAString_internal&) ()
   from /var/tmp/moz-build-dir/dist/bin/
(gdb) bt
#0  0x00007fffeee4089c in gfxFontUtils::DecodeFontName(char const*, int, unsigned int, unsigned int, unsigned int, nsAString_internal&) ()
   from /var/tmp/moz-build-dir/dist/bin/
#1  0x00007fffeee40c1f in gfxFontUtils::ReadNames(char const*, unsigned int, unsigned int, int, int, nsTArray<nsString>&) () from /var/tmp/moz-build-dir/dist/bin/
#2  0x00007fffeee40fbd in gfxFontUtils::ReadCanonicalName(char const*, unsigned int, unsigned int, nsString&) () from /var/tmp/moz-build-dir/dist/bin/
#3  0x00007fffeee411d0 in gfxFontUtils::ReadCanonicalName(hb_blob_t*, unsigned int, nsString&) () from /var/tmp/moz-build-dir/dist/bin/
#4  0x00007fffeee4126e in gfxFontUtils::GetFullNameFromTable(hb_blob_t*, nsAString_internal&) () from /var/tmp/moz-build-dir/dist/bin/
#5  0x00007fffeee4157e in gfxFontUtils::GetFullNameFromSFNT(unsigned char const*, unsigned int, nsAString_internal&) () from /var/tmp/moz-build-dir/dist/bin/
#6  0x00007fffeee8a877 in gfxUserFontEntry::LoadPlatformFont(unsigned char const*, unsigned int&) () from /var/tmp/moz-build-dir/dist/bin/
#7  0x00007fffeee8c17d in gfxUserFontEntry::FontDataDownloadComplete(unsigned char const*, unsigned int, nsresult) () from /var/tmp/moz-build-dir/dist/bin/
#8  0x00007ffff0d45cf8 in nsFontFaceLoader::OnStreamComplete(nsIStreamLoader*, nsISupports*, nsresult, unsigned int, unsigned char const*) ()
   from /var/tmp/moz-build-dir/dist/bin/
#9  0x00007fffee14598e in nsStreamLoader::OnStopRequest(nsIRequest*, nsISupports*, nsresult) () from /var/tmp/moz-build-dir/dist/bin/
#10 0x00007ffff0409d74 in nsCORSListenerProxy::OnStopRequest(nsIRequest*, nsISupports*, nsresult) () from /var/tmp/moz-build-dir/dist/bin/
#11 0x00007fffee396f92 in mozilla::net::nsHttpChannel::OnStopRequest(nsIRequest*, nsISupports*, nsresult) () from /var/tmp/moz-build-dir/dist/bin/
#12 0x00007fffee0e0f00 in nsInputStreamPump::OnStateStop() () from /var/tmp/moz-build-dir/dist/bin/
#13 0x00007fffee0e15ce in nsInputStreamPump::OnInputStreamReady(nsIAsyncInputStream*) () from /var/tmp/moz-build-dir/dist/bin/
#14 0x00007fffedf8c838 in nsInputStreamReadyEvent::Run() () from /var/tmp/moz-build-dir/dist/bin/
#15 0x00007fffedfcffc2 in nsThread::ProcessNextEvent(bool, bool*) () from /var/tmp/moz-build-dir/dist/bin/
#16 0x00007fffee0088d0 in NS_ProcessNextEvent(nsIThread*, bool) () from /var/tmp/moz-build-dir/dist/bin/
#17 0x00007fffee45b48b in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) () from /var/tmp/moz-build-dir/dist/bin/
#18 0x00007fffee42c9b6 in MessageLoop::Run() () from /var/tmp/moz-build-dir/dist/bin/
#19 0x00007ffff09d26f8 in nsBaseAppShell::Run() () from /var/tmp/moz-build-dir/dist/bin/
#20 0x00007ffff155aaab in nsAppStartup::Run() () from /var/tmp/moz-build-dir/dist/bin/
#21 0x00007ffff15c58ff in XREMain::XRE_mainRun() () from /var/tmp/moz-build-dir/dist/bin/
#22 0x00007ffff15c6e81 in XREMain::XRE_main(int, char**, nsXREAppData const*) () from /var/tmp/moz-build-dir/dist/bin/
#23 0x00007ffff15c731b in XRE_main () from /var/tmp/moz-build-dir/dist/bin/
#24 0x0000000000404d8b in do_main(int, char**, nsIFile*) [clone .constprop.0] ()
#25 0x0000000000403acf in main ()
We've had one report of these recently in the current release (Fennec 48).
Whiteboard: [native-crash] → [native-crash][gfx-noted]
I can confirm, that the bug is triggered by gcc 4.9.
Recompiling with gcc 4.8.5 (with otherwise unchanged system) supresses the bug.
I tested a little bit - all builds same build and execution environmet:

gcc-4.8.5 -O2: no crash
gcc-4.8.5 -O3: no crash
gcc-4.9.3 -O2: no crash
gcc-4.9.3 -O3: crash
gcc-5.3.0 -O2: no crash
gcc-5.3.0 -O3: crash
My guess is that we're inadvertently running into undefined C++ behavior, or making an unsafe assumption of some kind, and newer GCC has an optimization that is taking advantage of this in a way that results in the crash.

It might be useful to run one of the crashing builds under valgrind, and see if that reports anything of interest.
OK, figured out what's happening here. The problem arises because strings in the OpenType 'name' table do not necessarily have any particular alignment; specifically, the byte data for a UTF16LE-encoded string may start at any byte address. But DecodeFontName rashly casts the pointer to the byte data to a uint16_t* which it passes to CopySwapUTF16. With reasonably recent gcc and opt level -O3, this fails because the compiler unrolls and optimizes the loop in CopySwapUTF16 to something that uses movdqa to grab a quadword at a time. That opcode requires aligned data, which is not guaranteed here. A possible fix would be to annotate the relevant pointers with __unaligned (thus forcing the compiler to use a slower operation to access the data), but it seems simpler to just operate directly on the individual bytes. Any perf difference isn't going to be noticeable here, in comparison to everything else we're doing with the font data.
Attachment #8794916 - Flags: review?(jmuizelaar)
Assignee: nobody → jfkthame
Attachment #8794916 - Flags: review?(jmuizelaar) → review+
(In reply to Jonathan Kew (:jfkthame) from comment #10)
> specifically, the byte data for a UTF16LE-encoded string may start at any
> byte address. But DecodeFontName rashly casts the pointer to the byte data
> to a uint16_t* which it passes to CopySwapUTF16.

Just FTR, minor correction to this comment: Unicode strings in the 'name' table are of course UTF16*BE*-encoded, which is why we have to byte-swap the data when running on a little-endian platform.
Bug 757366 - Don't cast pointers to 'name'-table data to uint16_t*, as they may not be 16-bit-aligned. r=jrmuizel
Closed: 8 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla52
You need to log in before you can comment on or make changes to this bug.