Open Bug 1610518 Opened 5 years ago Updated 2 years ago

Menu and button text is missing on Solaris SPARC

Categories

(Core :: Widget: Gtk, defect, P5)

68 Branch
defect

Tracking

()

UNCONFIRMED

People

(Reporter: petr.sumbera, Unassigned, NeedInfo)

Details

Attachments

(8 files)

Attached image profile.jpg

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0

Steps to reproduce:

I see this with Firefox 68 (I'm not able to build latest Firefox sources now and the last version which really worked was 52 - which was 32bits).

Please see attached screen shot for more information.

Attached image tabc-close.jpg
Attached image menu.jpg
Component: Untriaged → Widget: Gtk
Product: Firefox → Core

I'm looking for advice how to debug it with binary with debug information.

I was hoping to be able to confirm that nsWindowWatcher::OpenWindow as it's called from JavaScript gets correct arguments in aArguments (I mean text values for buttons). Unfortunately I don't know how to do it...

Or maybe where should I look for Gtk button drawing? Any suggestion? Thanks!

You can run firefox with

MOZ_LOG="Widget:5"

and see on terminal actual widget sizes.

I guess it's gtk theme bug where button sizes are wrongly reported.
It's also possible that you're missing some system fonts or so.
Do you see any error message when firefox is running on terminal?

Following is console output of firefox -P with MOZ_LOG="Widget:5":

[5798, Main Thread] WARNING: dependent window created without a parent: file /builds/psumbera/FIREFOX/toolkit/components/startup/nsAppStartup.cpp, line 626
[(null) 5798: Main Thread]: D/Widget nsWindow::NativeResize [7d5ef4c31c00] 1 1
[(null) 5798: Main Thread]: D/Widget moz_container_init [7d5f282b2d60]
[(null) 5798: Main Thread]: D/Widget nsLookAndFeel::EnsureInit() [7d5ef4c3ec00] Chrome process
[(null) 5798: Main Thread]: D/Widget nsWindow [7d5ef4c31c00] Popup
[(null) 5798: Main Thread]: D/Widget    mShell 7d5ef4c36260 mContainer 7d5f282b2d60 mGdkWindow 7d5f282d1f80 0x2400003
[(null) 5798: Main Thread]: D/Widget GetScreenBounds [7d5ef4c31c00] 0,0 -> 1 x 1, unscaled 0,0 -> 1 x 1
[(null) 5798: Main Thread]: D/Widget nsWindow::SetModal [7d5ef4c31c00] 1
[5798, Main Thread] WARNING: NS_ENSURE_TRUE(root) failed: file /builds/psumbera/FIREFOX/layout/base/nsDocumentViewer.cpp, line 3105
[(null) 5798: Main Thread]: D/Widget nsWindow::SetSizeMode [7d5ef4c31c00] 0
[(null) 5798: Main Thread]: D/Widget     already set
[(null) 5798: Main Thread]: D/Widget GetScreenBounds [7d5ef4c31c00] 0,0 -> 1 x 1, unscaled 0,0 -> 1 x 1
[(null) 5798: Main Thread]: D/Widget GetScreenBounds [7d5ef4c31c00] 0,0 -> 1 x 1, unscaled 0,0 -> 1 x 1
[(null) 5798: Main Thread]: D/Widget nsWindow::Move [7d5ef4c31c00] 511.000000 338.000000
[(null) 5798: Main Thread]: D/Widget nsWindow::SetSizeMode [7d5ef4c31c00] 0
[(null) 5798: Main Thread]: D/Widget     already set
[(null) 5798: Main Thread]: D/Widget nsWindow::NativeMove [7d5ef4c31c00] 511 338
[(null) 5798: Main Thread]: D/Widget GetScreenBounds [7d5ef4c31c00] 0,0 -> 1 x 1, unscaled 0,0 -> 1 x 1
[(null) 5798: Main Thread]: D/Widget nsWindow::SetSizeMode [7d5ef4c31c00] 0
[(null) 5798: Main Thread]: D/Widget     already set
[(null) 5798: Main Thread]: D/Widget nsWindow::Resize [7d5ef4c31c00] 440 345
[(null) 5798: Main Thread]: D/Widget nsWindow::ResizeInt [7d5ef4c31c00] 0 0 -> 440 345 repaint 1
[(null) 5798: Main Thread]: D/Widget nsWindow::NativeResize [7d5ef4c31c00] 440 345
[(null) 5798: Main Thread]: D/Widget nsWindow::SetSizeMode [7d5ef4c31c00] 0
[(null) 5798: Main Thread]: D/Widget     already set
[(null) 5798: Main Thread]: D/Widget GetScreenBounds [7d5ef4c31c00] 0,0 -> 440 x 345, unscaled 0,0 -> 440 x 345
[(null) 5798: Main Thread]: D/Widget nsWindow::Move [7d5ef4c31c00] 292.000000 193.000000
[(null) 5798: Main Thread]: D/Widget nsWindow::SetSizeMode [7d5ef4c31c00] 0
[(null) 5798: Main Thread]: D/Widget     already set
[(null) 5798: Main Thread]: D/Widget nsWindow::NativeMove [7d5ef4c31c00] 292 193
[(null) 5798: Main Thread]: D/Widget GetScreenBounds [7d5ef4c31c00] 0,0 -> 440 x 345, unscaled 0,0 -> 440 x 345
[(null) 5798: Main Thread]: D/Widget nsWindow::Show [7d5ef4c31c00] state 1
[GFX2-]: Failed to lock WindowSurface, falling back to XPutImage backend.
[(null) 5798: Main Thread]: D/Widget nsWindow::OnWindowStateEvent [7d5ef4c31c00] for 7d5ef4c36260 changed 0x81 new_window_state 0x80
[(null) 5798: Main Thread]: D/Widget    early return because no interesting bits changed
[(null) 5798: Main Thread]: D/Widget nsWindow::OnWindowStateEvent [7d5ef4c31c00] for 7d5f282b2d60 changed 0x81 new_window_state 0x80
[(null) 5798: Main Thread]: D/Widget    quick return because IS_MOZ_CONTAINER(aWidget) is true
[(null) 5798: Main Thread]: D/Widget GetScreenBounds [7d5ef4c31c00] 292,193 -> 440 x 345, unscaled 292,193 -> 440 x 345
[(null) 5798: Main Thread]: D/Widget configure event [7d5ef4c31c00] 292 230 440 345
[(null) 5798: Main Thread]: D/Widget GetScreenBounds [7d5ef4c31c00] 292,193 -> 440 x 345, unscaled 292,193 -> 440 x 345
[(null) 5798: Main Thread]: D/Widget nsWindow::UpdateClientOffsetFromFrameExtents [7d5ef4c31c00] 0,37
[(null) 5798: Main Thread]: D/Widget configure event [7d5ef4c31c00] 292 230 440 345
[(null) 5798: Main Thread]: D/Widget GetScreenBounds [7d5ef4c31c00] 292,193 -> 440 x 345, unscaled 292,193 -> 440 x 345
[(null) 5798: Main Thread]: D/Widget configure event [7d5ef4c31c00] 292 230 440 345
[(null) 5798: Main Thread]: D/Widget GetScreenBounds [7d5ef4c31c00] 292,193 -> 440 x 345, unscaled 292,193 -> 440 x 345
[(null) 5798: Main Thread]: D/Widget moz_container_size_allocate [7d5f282b2d60] 0,0 -> 440 x 345
[(null) 5798: Main Thread]: D/Widget nsWindow::OnSizeAllocate [7d5ef4c31c00] 0,0 -> 440 x 345
[(null) 5798: Main Thread]: D/Widget key_press_event_cb
[(null) 5798: Main Thread]: D/Widget key_release_event_cb

The situation improved with ESR version 78. Now in latest trunk I'm aware only of limited problem in "Choose User Profile".

On left: i386 Solaris
On right: SPARC Solaris

When trying to identify the problem I'm comparing console output between i386 and SPARC.

First relevant difference is:

i386:

[Parent 17340: Main Thread]: D/Widget nsWindow::ApplySizeConstraints [7fc3bb211c00] min size 260 281
[Parent 17340: Main Thread]: D/Widget nsWindow::ApplySizeConstraints [7fc3bb211c00] max size 8192 8192

SPARC:

[Parent 29210: Main Thread]: D/Widget nsWindow::ApplySizeConstraints [7c7d61842000] min size 260 281
[Parent 29210: Main Thread]: D/Widget nsWindow::ApplySizeConstraints [7c7d61842000] max size 16384 16384

Max Size seems to be MOZ_WIDGET_MAX_SIZE . But I cannot find where it gets changed on i386. Also when run it in gdb it's 16384 too.

Nicolas, can you please advice where and how widget max size changes?

Flags: needinfo?(nical.bugzilla)

Next interesting difference between i386 and SPARC.

i386:

[Parent 17340: Main Thread]: D/Widget nsWindow::Resize [7fc3bb211c00] 440.000000 365.000000
[Parent 17340: Main Thread]: D/Widget nsWindow::ResizeInt [7fc3bb211c00] x:0 y:0 -> w:440 h:365 repaint 1 aMove 0
[Parent 17340: Main Thread]: D/Widget   ConstrainSize: w:440 h;365
[Parent 17340: Main Thread]: D/Widget nsWindow::NativeResize [7fc3bb211c00] 440 365

SPARC:

[Parent 29210: Main Thread]: D/Widget nsWindow::Resize [7c7d61842000] 440.000000 345.000000
[Parent 29210: Main Thread]: D/Widget nsWindow::ResizeInt [7c7d61842000] x:0 y:0 -> w:440 h:345 repaint 1 aMove 0
[Parent 29210: Main Thread]: D/Widget   ConstrainSize: w:440 h;345
[Parent 29210: Main Thread]: D/Widget nsWindow::NativeResize [7c7d61842000] 440 345

The difference of height 20 is probably just size of the missing text in the button.

Nicolas, can you please advice where and how widget max size changes?

The max texture size comes from a query to the opengl context, so it will change depending on hardware and driver versions. You are guaranteed to get at least 4k which is more than enough to render this window. I don't think the max texture size matters for the issue you are looking at, because it doesn't influence the layout (position and size of visual elements), and from your screenshots, the layout of these buttons (and as a result the size of the containing panel) is affected by the issue. Perhaps there is an issue related to the text in these buttons, causing them to get no size at all, maybe a font or font variation fails to load or some issue related to localization?

Flags: needinfo?(nical.bugzilla)

Martin, can you please point me where the text labels are set for the buttons?

I'm looking at:
https://searchfox.org/mozilla-central/source/widget/gtk/WidgetStyleCache.cpp#130
But there is just "M"!?

I would like to use dtrace or gdb to look at string which is being sent to gtk3..

Flags: needinfo?(stransky)

(In reply to Petr Sumbera from comment #11)

Martin, can you please point me where the text labels are set for the buttons?

I'm looking at:
https://searchfox.org/mozilla-central/source/widget/gtk/WidgetStyleCache.cpp#130
But there is just "M"!?

I would like to use dtrace or gdb to look at string which is being sent to gtk3..

It's a bit unfortunate you see that on ProfileManager only as you can't use developer tools there.

I ques the buttons are missing content so they are rendered as empty. The text comes from string budles (i.e. translation).

The localized strings are here:
https://searchfox.org/mozilla-central/source/toolkit/locales/en-US/toolkit/global/profileSelection.ftl#15

And the related XUL code is here:
https://searchfox.org/mozilla-central/source/toolkit/profile/content/profileSelection.xhtml#23

You can try to fiddle with the xul code to make buttons bigger or change the text in buttons.

You can also adjust minimal button sizes at nsNativeThemeGTK::GetMinimumWidgetSize() but I don't think it's a problem here as the may be bigger after it but still empty.

Flags: needinfo?(stransky)

(In reply to Martin Stránský [:stransky] (ni? me) from comment #12)

I ques the buttons are missing content so they are rendered as empty. The text comes from string budles (i.e. translation).

The localized strings are here:
https://searchfox.org/mozilla-central/source/toolkit/locales/en-US/toolkit/global/profileSelection.ftl#15

I have tried to modify .label and add .accesskey in profileSelection.ftl. But it didn't make any change (access key didn't work too).

And the related XUL code is here:
https://searchfox.org/mozilla-central/source/toolkit/profile/content/profileSelection.xhtml#23

You can try to fiddle with the xul code to make buttons bigger or change the text in buttons.

Following doesn't make any change - there are still empty buttons:

-  buttonidaccept="profile-selection-button-accept"
+  buttonidaccept="profile-selection-delete-button"

While this changes the text as expected:

-      <button id="newbutton" data-l10n-id="profile-selection-new-button"
+      <button id="newbutton" data-l10n-id="profile-selection-button-cancel"

You can also adjust minimal button sizes at nsNativeThemeGTK::GetMinimumWidgetSize() but I don't think it's a problem here as the may be bigger after it but still empty.

This really makes the change (see the picture). Empty buttons have right height now.

--- a/widget/gtk/nsNativeThemeGTK.cpp   Fri Mar 05 16:07:26 2021 +0100
+++ b/widget/gtk/nsNativeThemeGTK.cpp   Wed Mar 31 14:48:35 2021 +0200
@@ -1615,7 +1615,7 @@
       GetCachedWidgetBorder(aFrame, aAppearance, GetTextDirection(aFrame),
                             &border);
       aResult->width += border.left + border.right;
-      aResult->height += border.top + border.bottom;
+      aResult->height += border.top + border.bottom + 20;
     } break;
     case StyleAppearance::NumberInput:
     case StyleAppearance::Textfield: {

Any suggestion here? I think I need to get somewhere inside xul where the buttons texts are rendered...

Attached image firefox-P-1button.jpg

I have minimized profileSelection.xhtml and profileSelection.ftl to just one button. The issue is still there (see picture).

Interesting is when I modify toolkit/content/widgets/dialog.js here:

https://searchfox.org/mozilla-central/rev/3de2db87f3c9001ae478318d47a2ca3427574382/toolkit/content/widgets/dialog.js#390

to not call document.l10n.setAttributes() but rather:

button.setAttribute("label", this.getAttribute("buttonid" + dlgtype));

the dialog button now has some text ('profile-selection-button-cancel' - the same what I see on i386) even on SPARC!

I'm trying to verify whether the string 'profile-selection-button-cancel' gets from Javascript interpreter into DOMLocalization::SetAttributes():
https://searchfox.org/mozilla-central/rev/3de2db87f3c9001ae478318d47a2ca3427574382/dom/l10n/DOMLocalization.cpp#127

And I see there is some difference between SPARC and i386 here in how nsAString/char_16_t strings are supposed to work in regards of big endian byte swap:

#0  mozilla::dom::DOMLocalization_Binding::setAttributes(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&)
    (cx_=0x7fdc2922f000, obj=..., void_self=0x7fdc2e089740, args=...) at DOMLocalizationBinding.cpp:262
#1  0x00007fdc4d923331 in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) () at /builds/psumbera/FIREFOX-INSTALL/lib/firefox/libxul.so
#2  0x00007fdc51e190a4 in CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), js::CallReason, JS::CallArgs const&) ()
    at /builds/psumbera/FIREFOX-INSTALL/lib/firefox/libxul.so
#3  0x00007fdc51deabd4 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason)
    (cx=0x7fdc2922f000, args=..., construct=js::NO_CONSTRUCT, reason=js::CallReason::Call) at /builds/psumbera/FIREFOX/js/src/vm/Interpreter.cpp:520
#4  0x00007fdc51deb034 in InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) (cx=0x7fdc2922f000, args=..., reason=js::CallReason::Call)
    at /builds/psumbera/FIREFOX/js/src/vm/Interpreter.cpp:580
#5  0x00007fdc51deb07c in js::CallFromStack(JSContext*, JS::CallArgs const&) (cx=0x7fdc2922f000, args=...) at /builds/psumbera/FIREFOX/js/src/vm/Interpreter.cpp:584
#6  0x00007fdc528c5ad4 in js::jit::DoCallFallback(JSContext*, js::jit::BaselineFrame*, js::jit::ICCall_Fallback*, unsigned int, JS::Value*, JS::MutableHandle<JS::Value>)

Specifically:

https://searchfox.org/mozilla-central/source/__GENERATED__/dom/bindings/DOMLocalizationBinding.cpp#260

after calling ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1) I see following:

i386:

(gdb) print arg1.mLength
$4 = 31
(gdb) x/62c arg1.mData
0x7fdc265073d8:   112 'p' 0 '\000'        114 'r' 0 '\000'        111 'o' 0 '\000'        102 'f' 0 '\000'
0x7fdc265073e0:   105 'i' 0 '\000'        108 'l' 0 '\000'        101 'e' 0 '\000'        45 '-'  0 '\000'
0x7fdc265073e8:   115 's' 0 '\000'        101 'e' 0 '\000'        108 'l' 0 '\000'        101 'e' 0 '\000'
0x7fdc265073f0:   99 'c'  0 '\000'        116 't' 0 '\000'        105 'i' 0 '\000'        111 'o' 0 '\000'
0x7fdc265073f8:   110 'n' 0 '\000'        45 '-'  0 '\000'        98 'b'  0 '\000'        117 'u' 0 '\000'
0x7fdc26507400:   116 't' 0 '\000'        116 't' 0 '\000'        111 'o' 0 '\000'        110 'n' 0 '\000'
0x7fdc26507408:   45 '-'  0 '\000'        99 'c'  0 '\000'        97 'a'  0 '\000'        110 'n' 0 '\000'
0x7fdc26507410:   99 'c'  0 '\000'        101 'e' 0 '\000'        108 'l' 0 '\000'

SPARC:

(gdb) print arg1.mLength
$8 = 31
(gdb) x/62c arg1.mData
0x7bfa08eee438: 0 '\000'        112 'p' 0 '\000'        114 'r' 0 '\000'        111 'o' 0 '\000'        102 'f'
0x7bfa08eee440: 0 '\000'        105 'i' 0 '\000'        108 'l' 0 '\000'        101 'e' 0 '\000'        45 '-'
0x7bfa08eee448: 0 '\000'        115 's' 0 '\000'        101 'e' 0 '\000'        108 'l' 0 '\000'        101 'e'
0x7bfa08eee450: 0 '\000'        99 'c'  0 '\000'        116 't' 0 '\000'        105 'i' 0 '\000'        111 'o'
0x7bfa08eee458: 0 '\000'        110 'n' 0 '\000'        45 '-'  0 '\000'        98 'b'  0 '\000'        117 'u'
0x7bfa08eee460: 0 '\000'        116 't' 0 '\000'        116 't' 0 '\000'        111 'o' 0 '\000'        110 'n'
0x7bfa08eee468: 0 '\000'        45 '-'  0 '\000'        99 'c'  0 '\000'        97 'a'  0 '\000'        110 'n'
0x7bfa08eee470: 0 '\000'        99 'c'  0 '\000'        101 'e' 0 '\000'        108 'l'

Peter, do you have any insight into this? Can you please confirm that the byte swap is expected?

Flags: needinfo?(peterv)

Following "hack" makes the button look as expected:

--- a/toolkit/content/widgets/dialog.js Fri Mar 05 16:07:26 2021 +0100
+++ b/toolkit/content/widgets/dialog.js Wed Apr 14 12:04:09 2021 +0200
@@ -392,6 +392,7 @@
               this.getAttribute("buttonid" + dlgtype)
             );
             this._l10nButtons.push(button);
+            button.setAttribute("label", "");
           } else if (dlgtype != "extra1" && dlgtype != "extra2") {
             button.setAttribute(
               "label",

This doesn't make much sense for me. The added line can be added even two commands above and it still helps. So this probably rule out DOMLocalization::SetAttributes() and byte swapped strings?!

To me it seems more likely related to Javascript interpreter on SPARC (though not sure how localization works after SetAttributes() is called).

Jan, do you have any suggestion?

Component: Widget: Gtk → JavaScript Engine
Flags: needinfo?(peterv) → needinfo?(jdemooij)

(In reply to Petr Sumbera from comment #16)

after calling ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1) I see following:

How does the data in args[1] look?

(In reply to Peter Van der Beken [:peterv] from comment #18)

(In reply to Petr Sumbera from comment #16)

after calling ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1) I see following:

How does the data in args[1] look?

How can I look at it?

I can see only this. But where is the string?

(gdb) print args[1]
$6 = {<js::MutableHandleBase<JS::Value, JS::MutableHandle<JS::Value> >> = {<js::MutableWrappedPtrOperations<JS::Value, JS::MutableHandle<JS::Value> >> = {<js::WrappedPtrOperations<JS::Value, JS::MutableHandle<JS::Value> >> = {<No data fields>}, <No data fields>}, <No data fields>}, ptr = 0x7bce7a221290}
(gdb) x/16x args[1].ptr
0x7bce7a221290: 0xff    0xfb    0x04    0x35    0x36    0x0a    0x21    0xd8
0x7bce7a221298: 0xff    0xfe    0x04    0x35    0x36    0x07    0xd7    0x60

You could add a js::DumpValue(args[1]); call to dump that value in a debug build. You may have to include this header for that to work.

Try stepping through the DOMLocalization code to see what it ends up doing exactly on x86 vs SPARC?

Flags: needinfo?(jdemooij)

(In reply to Jan de Mooij [:jandem] from comment #21)

You could add a js::DumpValue(args[1]); call to dump that value in a debug build. You may have to include this header for that to work.

args[1] for both i386 and SPARC looks fine:

i386:
JSString* (42f508a81d8) = char16_t * (7fd56597ae78) = "profile-selection-button-cancel"

SPARC:
JSString* (112f679a21d8) = char16_t * (7980dbef1e78) = "profile-selection-button-cancel"

Try stepping through the DOMLocalization code to see what it ends up doing exactly on x86 vs SPARC?

I have already did it for DOMLocalization::SetAttributes(). But I believe there was nothing suspicious. The attribute was just set.
I wonder where should I set break point next?
Where is done the string loading, translation and how it gets propagated to the button?

Thank you!

Flags: needinfo?(jdemooij)

(In reply to Petr Sumbera from comment #22)

I wonder where should I set break point next?
Where is done the string loading, translation and how it gets propagated to the button?

I can't really help you with this, I mainly work on the JS engine so I'm not familiar with that code either. What I would do is see where DOMLocalization::SetAttributes ends up storing the attribute exactly, and then add some logging there + at the point where it reads these attributes (GetAttr? GetAttributes?).

Flags: needinfo?(jdemooij)

Based on the comments here, this doesn't seem like an engine bug. Moving back to Widget: gtk.

Component: JavaScript Engine → Widget: Gtk

You can check how the elements are positioned/sized by reflow debug. Run Firefox DEBUG build with:

GECKO_DISPLAY_REFLOW_PROCESSES=a

env variable and you should see size of the elements (looks for HTMLButton element or so). I guess it may be a problem with fonts - a missing font may make the button empty.

Priority: -- → P5

(In reply to Petr Sumbera from comment #17)

Following "hack" makes the button look as expected:
--- a/toolkit/content/widgets/dialog.js Fri Mar 05 16:07:26 2021 +0100
+++ b/toolkit/content/widgets/dialog.js Wed Apr 14 12:04:09 2021 +0200
@@ -392,6 +392,7 @@
this.getAttribute("buttonid" + dlgtype)
);
this._l10nButtons.push(button);

  •        button.setAttribute("label", "");
    

Meanwhile I was digging how this hack can help. I was trying to prematurely end call to Element::SetAttr() and subsequent methods.

See below which change still allows the above workaround to work.

diff -r 43e54e470d0d dom/base/AttrArray.cpp
--- a/dom/base/AttrArray.cpp    Fri Mar 05 16:07:26 2021 +0100
+++ b/dom/base/AttrArray.cpp    Wed Apr 21 12:47:59 2021 +0200
@@ -111,6 +111,7 @@

 template <typename Name>
 inline nsresult AttrArray::AddNewAttribute(Name* aName, nsAttrValue& aValue) {
+  static int mycount=0; printf("AttrArray::AddNewAttribute[%d]\n", ++mycount);
   MOZ_ASSERT(!mImpl || mImpl->mCapacity >= mImpl->mAttrCount);
   if (!mImpl || mImpl->mCapacity == mImpl->mAttrCount) {
     if (!GrowBy(1)) {
@@ -118,9 +119,11 @@
     }
   }

+  // if (mycount==99) return NS_OK; // button without text
   InternalAttr& attr = mImpl->mBuffer[mImpl->mAttrCount++];
   new (&attr.mName) nsAttrName(aName);
   new (&attr.mValue) nsAttrValue();
+  if (mycount==99) return NS_OK;   // ok - button with text
   attr.mValue.SwapValueWith(aValue);
   return NS_OK;
 }

Note that aName is "label" and aValue (nsAttrValue::eAtom) is string as provided in the hack "".

Following is (deepest) stack of the hack call (button.setAttribute("label", "")) - premature return is in #1.

#0  nsAttrValue::SwapValueWith(nsAttrValue&) (this=0x7b29d8223c28, aOther=...) at /builds/psumbera/FIREFOX/dom/base/nsAttrValue.cpp:503
#1  0x00007b29f4282624 in nsresult AttrArray::AddNewAttribute<nsAtom>(nsAtom*, nsAttrValue&) () at /builds/psumbera/FIREFOX-INSTALL/lib/firefox/libxul.so
#2  0x00007b29f424ed38 in AttrArray::SetAndSwapAttr(nsAtom*, nsAttrValue&, bool*)
    (this=0x7b29d7c02e80, aLocalName=0x7b29ee27a5a4 <mozilla::detail::gGkAtoms+67156>, aValue=..., aHadValue=0x7c75bf91b2e1)
    at /builds/psumbera/FIREFOX/dom/base/AttrArray.cpp:140
#3  0x00007b29f43b3188 in mozilla::dom::Element::SetAttrAndNotify(int, nsAtom*, nsAtom*, nsAttrValue const*, nsAttrValue&, nsIPrincipal*, unsigned char, bool, bool, bool, mozilla::dom::Document*, mozAutoDocUpdate const&)
    (this=0x7b29d7c02e00, aNamespaceID=0, aName=0x7b29ee27a5a4 <mozilla::detail::gGkAtoms+67156>, aPrefix=0x0, aOldValue=0x0, aParsedValue=..., aSubjectPrincipal=0x0, aModType=2 '\002', aFireMutation=false, aNotify=true, aCallAfterSetAttr=true, aComposedDocument=0x7b29d826e000) at /builds/psumbera/FIREFOX/dom/base/Element.cpp:2435
#4  0x00007b29f43b291c in mozilla::dom::Element::SetAttr(int, nsAtom*, nsAtom*, nsTSubstring<char16_t> const&, nsIPrincipal*, bool)
    (this=0x7b29d7c02e00, aNamespaceID=0, aName=0x7b29ee27a5a4 <mozilla::detail::gGkAtoms+67156>, aPrefix=0x0, aValue=..., aSubjectPrincipal=0x0, aNotify=true)
    at /builds/psumbera/FIREFOX/dom/base/Element.cpp:2360
#5  0x00007b29f43fc0c4 in mozilla::dom::Element::SetAttr(int, nsAtom*, nsTSubstring<char16_t> const&, nsIPrincipal*, bool) ()
    at /builds/psumbera/FIREFOX-INSTALL/lib/firefox/libxul.so
#6  0x00007b29f43ace94 in mozilla::dom::Element::SetAttribute(nsTSubstring<char16_t> const&, nsTSubstring<char16_t> const&, nsIPrincipal*, mozilla::ErrorResult&)
    (this=0x7b29d7c02e00, aName=..., aValue=..., aTriggeringPrincipal=0x0, aError=...) at /builds/psumbera/FIREFOX/dom/base/Element.cpp:1421
#7  0x00007b29f59e77c8 in mozilla::dom::Element_Binding::setAttribute(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&)
    (cx=0x7b29dae21000, obj=..., void_self=0x7b29d7c02e00, args=...) at ElementBinding.cpp:1348
..

(In reply to Martin Stránský [:stransky] (ni? me) from comment #25)

You can check how the elements are positioned/sized by reflow debug. Run Firefox DEBUG build with:

GECKO_DISPLAY_REFLOW_PROCESSES=a

What should I look for in the output? I see that there is no 'TextBox(label)' at all. While with the workaround there is:

with workaround:

..
       Box 7cf78d96ca38 GetPrefSize
        ImageBox(image)(0) 7cf78d96cb08 GetPrefSize
         ImageBox(image)(0) 7cf78d96cb08 GetMinSize
         ImageBox(image)(0) 7cf78d96cb08 GetMinSize=0,0
         ImageBox(image)(0) 7cf78d96cb08 GetMaxSize
         ImageBox(image)(0) 7cf78d96cb08 GetMaxSize=UC,UC
        ImageBox(image)(0) 7cf78d96cb08 GetPrefSize=0,0
        TextBox(label)(1)[value=] 7cf78d96cbb8 GetPrefSize
        TextBox(label)(1)[value=] 7cf78d96cbb8 GetPrefSize=0,1200
        Box 7cf78d96ca38 GetMinSize
..

without workaround:

..
       Box 799f9db5ca38 GetPrefSize
        ImageBox(image)(0) 799f9db5cb08 GetPrefSize
         ImageBox(image)(0) 799f9db5cb08 GetMinSize
         ImageBox(image)(0) 799f9db5cb08 GetMinSize=0,0
         ImageBox(image)(0) 799f9db5cb08 GetMaxSize
         ImageBox(image)(0) 799f9db5cb08 GetMaxSize=UC,UC
        ImageBox(image)(0) 799f9db5cb08 GetPrefSize=0,0
        block 799f9db5cbb8 GetPrefSize
..

> env variable and you should see size of the elements (looks for HTMLButton element or so). I guess it may be a problem with fonts - a missing font may make the button empty.

I don't see anything like 'HTMLButton'. But lot of 'Box'es :-)

Do you still think it might be related to font? Even when I have workaround where the button contains the text. Thank you!
Flags: needinfo?(stransky)

(In reply to Petr Sumbera from comment #17)

Following "hack" makes the button look as expected:

> +            button.setAttribute("label", "");

It's really hack. I have just realized that it fails with assertion during exit:

Assertion failure: (run->mRegionsMask[elm] & (1U << bit)) == 0 (Double-free?), at /builds/psumbera/FIREFOX/memory/build/mozjemalloc.cpp:2209

https://searchfox.org/mozilla-central/rev/72951aa826642f048da4c6b71b8b3e36a9606dcd/memory/build/mozjemalloc.cpp#2209

Mike, can you please have look at above comment? Does the assertion suggest any specific bug? I think that adding the line into dialog.js shouldn't cause such issue. Maybe it can point to the main problem?

Flags: needinfo?(mh+mozilla)

You should compare reflow output (GECKO_DISPLAY_REFLOW_PROCESSES) on system where it works and where it fails. I don't have any particular layout experience.

Flags: needinfo?(stransky)

The assertion gives as much information as I'd be able to give: it's likely a double-free bug somewhere.

Flags: needinfo?(mh+mozilla)

Looking into DOMLocalization.cpp to see if missing text in the button on SPARC can be caused by localization. But below seems to be similar to what I see on x86. And there is "label" and "button text "Exit"...

https://searchfox.org/mozilla-central/rev/1ed1bb14eed9b3f27a94513387608436ea74c247/dom/l10n/L10nOverlays.cpp#172

(gdb) where
#0  mozilla::dom::L10nOverlays::OverlayAttributes(mozilla::dom::Nullable<mozilla::dom::Sequence<mozilla::dom::AttributeNameValue> > const&, mozilla::dom::Element*, mozilla:2#1  0x00007abfa866988c in mozilla::dom::L10nOverlays::TranslateElement(mozilla::dom::Element&, mozilla::dom::L10nMessage const&, nsTArray<mozilla::dom::L10nOverlaysError>&,3#2  0x00007abfa8660a70 in mozilla::dom::DOMLocalization::ApplyTranslations(nsTArray<nsCOMPtr<mozilla::dom::Element> >&, nsTArray<mozilla::dom::Nullable<mozilla::dom::L10nMe)
    at /builds/psumbera/FIREFOX/dom/l10n/DOMLocalization.cpp:498
#3  0x00007abfa866a86c in ElementTranslationHandler::ResolvedCallback(JSContext*, JS::Handle<JS::Value>) () at /builds/psumbera/FIREFOX-INSTALL/lib/firefox/libxul.so
#4  0x00007abfa8012b94 in mozilla::dom::(anonymous namespace)::PromiseNativeHandlerShim::ResolvedCallback(JSContext*, JS::Handle<JS::Value>)
    (this=0x7abf87633680, aCx=0x7abf8a224000, aValue=...) at /builds/psumbera/FIREFOX/dom/promise/Promise.cpp:384
#5  0x00007abfa80126c8 in mozilla::dom::NativeHandlerCallback(JSContext*, unsigned int, JS::Value*) (aCx=0x7abf8a224000, aArgc=1, aVp=0x7e0a8b4f32d0)
    at /builds/psumbera/FIREFOX/dom/promise/Promise.cpp:337
#6  0x00007abfab6d8c28 in CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), js::CallReason, JS::CallArgs const&) ()
    at /builds/psumbera/FIREFOX-INSTALL/lib/firefox/libxul.so
#7  0x00007abfab692e54 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason)
    (cx=0x7abf8a224000, args=..., construct=js::NO_CONSTRUCT, reason=js::CallReason::Call) at /builds/psumbera/FIREFOX/js/src/vm/Interpreter.cpp:520
...
(gdb) frame
#0  mozilla::dom::L10nOverlays::OverlayAttributes (aTranslation=..., aToElement=0x7abf87002620, aRv=...) at /builds/psumbera/FIREFOX/dom/l10n/L10nOverlays.cpp:172
172             aToElement->SetAttr(nameAtom, value, aRv);
(gdb) print *aToElement
$58 = {<mozilla::dom::FragmentOrElement> = {<nsIContent> = {<nsINode> = {<mozilla::dom::EventTarget> = {<nsISupports> = {
            _vptr.nsISupports = 0x7abfb70bdd08 <vtable for nsXULElement+16>}, <nsWrapperCache> = {_vptr.nsWrapperCache = 0x7abfb70be008 <vtable for nsXULElement+784>,
            mWrapper = 0x2636aa871670, mFlags = 67, mBoolFlags = 1074266140}, <No data fields>}, static ELEMENT_NODE = 1, static ATTRIBUTE_NODE = 2, static TEXT_NODE = 3,
        static CDATA_SECTION_NODE = 4, static ENTITY_REFERENCE_NODE = 5, static ENTITY_NODE = 6, static PROCESSING_INSTRUCTION_NODE = 7, static COMMENT_NODE = 8,
        static DOCUMENT_NODE = 9, static DOCUMENT_TYPE_NODE = 10, static DOCUMENT_FRAGMENT_NODE = 11, static NOTATION_NODE = 12, static MAX_NODE_TYPE = 12, mNodeInfo = {
          mRawPtr = 0x7abf876ec900}, mParent = 0x7abf87002fb0, mChildCount = 1, mFirstChild = {mRawPtr = 0x7abf87003dc0}, mNextSibling = {mRawPtr = 0x7abf87002aa0},
        mPreviousOrLastSibling = 0x7abf87003160, {mPrimaryFrame = 0x7abf8ef68958, mSubtreeRoot = 0x7abf8ef68958}, mSlots = 0x7abf8ef4dc40}, mRefCnt = {
        mRefCntAndFlags = 23}, _mOwningThread = {mThread = 0x7abfc5daae20}, static _cycleCollectorGlobal =
    {<nsXPCOMCycleCollectionParticipant> = {<nsScriptObjectTracer> = {<nsCycleCollectionParticipant> = {
              _vptr.nsCycleCollectionParticipant = 0x7abfb6ffd750 <vtable for nsIContent::cycleCollection+16>, static FlagMightSkip = 1 '\001',
              static FlagTraverseShouldTrace = 2 '\002', static FlagMultiZoneJSHolder = 4 '\004', static AllFlags = 7 '\a',
              mFlags = 2 '\002'}, <No data fields>}, <No data fields>}, <No data fields>}, static sTabFocusModel = 7, static sTabFocusModelAppliesToXUL = false},
    static _cycleCollectorGlobal = {<nsIContent::cycleCollection> = {<nsXPCOMCycleCollectionParticipant> = {<nsScriptObjectTracer> = {<nsCycleCollectionParticipant> = {
              _vptr.nsCycleCollectionParticipant = 0x7abfb6ffd150 <vtable for mozilla::dom::FragmentOrElement::cycleCollection+16>, static FlagMightSkip = 1 '\001',
              static FlagTraverseShouldTrace = 2 '\002', static FlagMultiZoneJSHolder = 4 '\004', static AllFlags = 7 '\a',
              mFlags = 3 '\003'}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}}, static kAllServoDescendantBits = 1576960,
  static kFireMutationEvent = true, static kDontFireMutationEvent = false, static kNotifyDocumentObservers = true, static kDontNotifyDocumentObservers = false,
  static kCallAfterSetAttr = true, static kDontCallAfterSetAttr = false, mState = {mStates = 545259520}, mServoData = {mValue = 0x7abf87641360}, mAttrs = {mImpl = {
      mTuple = {<mozilla::detail::CompactPairHelper<AttrArray::Impl*, mozilla::DefaultDelete<AttrArray::Impl>, (mozilla::detail::StorageType)1, (mozilla::detail::StorageTyp}
(gdb) print *nameAtom
$59 = (nsAtom &) @0x7abf9e27a5a4: {mLength = 5, mIsStatic = 1, mIsAsciiLowercase = 1, mHash = 2384499441}
(gdb) x/6s nameAtom->GetUTF16String()
0x7abf9e26cddc <_ZN7mozilla6detail8gGkAtomsE+11916>:        ""
0x7abf9e26cddd <_ZN7mozilla6detail8gGkAtomsE+11917>:        "l"
0x7abf9e26cddf <_ZN7mozilla6detail8gGkAtomsE+11919>:        "a"
0x7abf9e26cde1 <_ZN7mozilla6detail8gGkAtomsE+11921>:        "b"
0x7abf9e26cde3 <_ZN7mozilla6detail8gGkAtomsE+11923>:        "e"
0x7abf9e26cde5 <_ZN7mozilla6detail8gGkAtomsE+11925>:        "l"
(gdb) print value
$60 = {<nsTAutoStringN<char16_t, 64>> = {<nsTString<char16_t>> = {<nsTSubstring<char16_t>> = {<mozilla::detail::nsTStringRepr<char16_t>> = {
          mData = 0x7e0a8b4f26f4 u<error reading variable>, mLength = 4,
          mDataFlags = (mozilla::detail::StringDataFlags::TERMINATED | mozilla::detail::StringDataFlags::INLINE),
          mClassFlags = (mozilla::detail::StringClassFlags::INLINE | mozilla::detail::StringClassFlags::NULL_TERMINATED)},
        static kMaxCapacity = 1073741817}, <No data fields>}, static kStorageSize = 64, mInlineCapacity = 63, mStorage = u<error reading variable>}, <No data fields>}
(gdb) x /5s value.mData
0x7e0a8b4f26f4:   ""
0x7e0a8b4f26f5:   "E"
0x7e0a8b4f26f7:   "x"
0x7e0a8b4f26f9:   "i"
0x7e0a8b4f26fb:   "t"

Zibi, can you please have look here? Does above suggest that localization works as expected? Do you see any other place where text "Exit" can be missing from the button? Thank you!

Flags: needinfo?(zbraniecki)

It does seem to work as expected.

If the Exit is present as a value of the attribute label in DOM, then l10n did it's job and you can exclude it from investigation. The question becomes why UI didn't react to that label?

Flags: needinfo?(zbraniecki)
Attached file log-reflow-SPARC.txt
Attached file log-reflow-i386.txt

I have attached log-reflow-i386.txt and log-reflow-SPARC.txt which are output of following run on i386 and SPARC:

GECKO_VERIFY_REFLOW_FLAGS="reflow,all,list-commands,noisy-commands,really-noisy-commands,resize" GECKO_DISPLAY_REFLOW_PROCESSES=a /builds/psumbera/FIREFOX-INSTALL/bin/firefox -P

Last common line (of course pointers differ) for both i386 and SPARC is line 676.

 Box 7ff335d4f5a0 GetMinSize=7224,2160
 Box 7ff335d4f5a0 GetMaxSize
 Box 7ff335d4f5a0 GetMaxSize=UC,UC <<< Last common line for i386 and SPARC

And then following can be seen only on i386:

DocElementBox(window)(-1) 7ff335d4f1b0 GetMaxSize=UC,UC

PresShell@7ff343495000: frame 7ff335d4fa38 needs reflow
Current content model:
XUL* window@7ff335902af0 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml" data-l10n-id="profile-selection-window" title="Choose User Profile" lang="en-US" localedir="ltr" chromehidden="menubar toolbar location directories status extrachrome " role="dialog" state=[20000000] flags=[00000000] primaryframe=7ff335d4f1b0 refcount=10<
  XUL* dialog@7ff335902550 id="profileWindow" buttons="cancel" buttonidcancel="profile-selection-button-cancel" defaultButton="accept" state=[20800000] flags=[00000002] primaryframe=7ff335d4f5a0 refcount=7<
    XUL* linkset@7ff335902160 state=[20000000] flags=[00008000] primaryframe=7ff335d4f740 refcount=5<
      html:link@7ff335904d60 rel="localization" href="toolkit/global/profileSelection.ftl" state=[100020800000] flags=[00008000] primaryframe=0 refcount=3<>
    >
    XUL* script@7ff335902820 src="chrome://global/content/customElements.js" state=[20000000] flags=[00008000] primaryframe=0 refcount=3<>
  >
>

PresShell@7ff343495000: frame 7ff335d4fa38 needs reflow
Current content model:
XUL* window@7ff335902af0 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml" data-l10n-id="profile-selection-window" title="Choose User Profile" lang="en-US" localedir="ltr" chromehidden="menubar toolbar location directories status extrachrome " role="dialog" state=[20000000] flags=[00000000] primaryframe=7ff335d4f1b0 refcount=10<
  XUL* dialog@7ff335902550 id="profileWindow" buttons="cancel" buttonidcancel="profile-selection-button-cancel" defaultButton="accept" state=[20800000] flags=[00000002] primaryframe=7ff335d4f5a0 refcount=7<
    XUL* linkset@7ff335902160 state=[20000000] flags=[00008000] primaryframe=7ff335d4f740 refcount=5<
      html:link@7ff335904d60 rel="localization" href="toolkit/global/profileSelection.ftl" state=[100020800000] flags=[00008000] primaryframe=0 refcount=3<>
    >
    XUL* script@7ff335902820 src="chrome://global/content/customElements.js" state=[20000000] flags=[00008000] primaryframe=0 refcount=3<>
  >
>
ProcessReflowCommands: begin incremental reflow
VP 7ff335d4f020 InitConstraints parent=0 cb=UC,UC as=60,UC b=0 p=0

And it continues and lists TextBoxes:

..
        TextBox(label)(1)[value=Exit] 7ff335d4fc80 GetPrefSize
        TextBox(label)(1)[value=Exit] 7ff335d4fc80 GetPrefSize=1380,1200
..

i386 then continues with the same as SPARC on line 978 but some numbers are now different:

VP 7f892ec66020 GetPrefISize
 xulroot 7f892ec660c8 GetPrefISize
  xulroot 7f892ec660c8 GetPrefSize
   DocElementBox(window)(-1) 7f892ec661b0 GetPrefSize
    PopupSet 7f892ec66298 GetPrefSize
    PopupSet 7f892ec66298 GetPrefSize=0,0
    place 7f892ec66520 GetPrefSize
    place 7f892ec66520 GetPrefSize=0,0
    Box 7f892ec665a0 GetPrefSize
    Box 7f892ec665a0 GetPrefSize=7224,3360  <<< SPARC has 7224,2160

Emilio, not sure who can help me with reflowing? I don't really know what it's really supposed to do.
Do you have any opinion or suggestion here? Why can SPARC miss part of data?

Flags: needinfo?(emilio)

So the best way to figure out the culprit for this, IMO, is using the browser toolbox. Is there text in those buttons?

You can do that with Ctrl+Shift+I, on a local build (you need to tweak some bits in regular builds).

Is the text missing in other bits apart from the profile selection dialog, like, let's say, the "about firefox" window or something similar? If so the above should be straight-forward. I don't know how easy is it to inspect the profile selection dialog otherwise though.

Flags: needinfo?(emilio) → needinfo?(petr.sumbera)
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: