Closed Bug 1612301 Opened 6 years ago Closed 5 years ago

Hit MOZ_CRASH(assertion failed: `(left == right)` left: `Length`, right: `Calc`) at servo/components/style/values/computed/length_percentage.rs:238 on big endian machine

Categories

(Core :: CSS Parsing and Computation, defect, P3)

defect

Tracking

()

RESOLVED FIXED
mozilla74
Tracking Status
firefox75 --- fixed

People

(Reporter: petr.sumbera, Assigned: emilio)

References

Details

Attachments

(5 files)

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 on Solaris SPARC (64bits) with latest Firefox sources:

Hit MOZ_CRASH(assertion failed: (left == right)
left: Length,
right: Calc) at servo/components/style/values/computed/length_percentage.rs:238

/// Private version of new_calc() that constructs a calc() variant without
    /// checking.
    fn new_calc_unchecked(calc: Box<CalcLengthPercentage>) -> Self {
        let ptr = Box::into_raw(calc);
        let calc = Self(LengthPercentageUnion {
            calc: CalcVariant {
                #[cfg(target_pointer_width = "32")]
                tag: LengthPercentageUnion::TAG_CALC,
                ptr,
            }
        });
        debug_assert_eq!(calc.tag(), Tag::Calc);          <=== !!!
        calc
    }

This was added via Bug 1607049 .

Emilio can you please have look at this?

Flags: needinfo?(emilio)

Hmm, so this is on a big-endian machine, right? I suspect our union trickery doesn't work for big-endian machines and we need to figure out something else...

Do you know how can I test this / emulate this? I don't have the right hardware.

Status: UNCONFIRMED → NEW
Component: Untriaged → CSS Parsing and Computation
Ever confirmed: true
Flags: needinfo?(emilio) → needinfo?(petr.sumbera)
Priority: -- → P3
Product: Firefox → Core
Summary: Hit MOZ_CRASH(assertion failed: `(left == right)` left: `Length`, right: `Calc`) at servo/components/style/values/computed/length_percentage.rs:238 → Hit MOZ_CRASH(assertion failed: `(left == right)` left: `Length`, right: `Calc`) at servo/components/style/values/computed/length_percentage.rs:238 on big endian machine
Target Milestone: --- → mozilla74

Yes, it's big-endian machine. I can just offer you to run some isolated tests on your requests (some simple Rust test code?).

Flags: needinfo?(petr.sumbera)

This should reproduce the issue. Haven't tried to make it work on big-endian yet.

Does this work for you? I'd like to fix it in a better way (so that it only takes 64 bits rather than growing the thing), but just confirming that you can repro this and that the problem goes away like this.

Flags: needinfo?(petr.sumbera)

I haven't looked into your code. But the second version seems to be fine.

$: ./reproduce
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Length`,
 right: `Calc`', reproduce.rs:149:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
$ ./fixed
$
Flags: needinfo?(petr.sumbera)

Does this work?

Flags: needinfo?(petr.sumbera)

Yes. No error output.

Flags: needinfo?(petr.sumbera)

Ok, I'll try to clean it up and send it for review tomorrow or sometime next week, probably.

Flags: needinfo?(petr.sumbera)

Err, sorry, that was supposed to be for me.

Flags: needinfo?(petr.sumbera) → needinfo?(emilio)

Thank you! I can also confirm that with your changes applied to Firefox tree (see below) I no longer see the assertion (though at the moment I'm hitting probably another bug - Bug 1612503).

--- a/servo/components/style/values/computed/length_percentage.rs       Wed Jan 29 15:38:48 2020 +0100
+++ b/servo/components/style/values/computed/length_percentage.rs       Fri Jan 31 10:24:54 2020 +0100
@@ -59,7 +59,7 @@
 #[doc(hidden)]
 #[derive(Copy, Clone)]
 #[repr(C)]
-#[cfg(target_pointer_width = "32")]
+#[cfg(any(target_endian = "big", target_pointer_width = "32"))]
 pub struct CalcVariant {
     tag: u32,
     ptr: *mut CalcLengthPercentage,
@@ -68,7 +68,7 @@
 #[doc(hidden)]
 #[derive(Copy, Clone)]
 #[repr(C)]
-#[cfg(target_pointer_width = "64")]
+#[cfg(all(target_endian = "little", target_pointer_width = "64"))]
 pub struct CalcVariant {
     ptr: *mut CalcLengthPercentage,
 }
@@ -127,15 +127,6 @@
     Percentage = LengthPercentageUnion::TAG_PERCENTAGE,
 }

-// All the members should be 64 bits, even in 32-bit builds.
-#[allow(unused)]
-unsafe fn static_assert() {
-    std::mem::transmute::<u64, LengthVariant>(0u64);
-    std::mem::transmute::<u64, PercentageVariant>(0u64);
-    std::mem::transmute::<u64, CalcVariant>(0u64);
-    std::mem::transmute::<u64, LengthPercentage>(0u64);
-}
-
 impl Drop for LengthPercentage {
     fn drop(&mut self) {
         if self.tag() == Tag::Calc {
@@ -230,7 +221,7 @@
         let ptr = Box::into_raw(calc);
         let calc = Self(LengthPercentageUnion {
             calc: CalcVariant {
-                #[cfg(target_pointer_width = "32")]
+                #[cfg(any(target_endian = "big", target_pointer_width = "32"))]
                 tag: LengthPercentageUnion::TAG_CALC,
                 ptr,
             }

Always store the pointer in little-endian order so that the tag trick works.

Assignee: nobody → emilio
Status: NEW → ASSIGNED

Can you confirm that the patch I submitted works for you?

Flags: needinfo?(emilio) → needinfo?(petr.sumbera)

(I wonder if we also need to store the tag in big-endian order... Otherwise you'd hit assertions I guess...)

I can confirm that the submitted patch works. I also don't see Bug 1612503. So it must had been related (I will close it now). Thank you!

Flags: needinfo?(petr.sumbera)
Pushed by ealvarez@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/4412f2791565 Fix LengthPercentage on big-endian machines. r=jfkthame
Pushed by ealvarez@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/b70256aaf4ba Add some comments as per jwatt's request.
Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: