Closed Bug 892291 Opened 11 years ago Closed 11 years ago

OdinMonkey: Crash [@ js::Invoke] or [@ js::CallJSNative]

Categories

(Core :: JavaScript Engine, defect)

x86
All
defect
Not set
critical

Tracking

()

VERIFIED FIXED
mozilla25
Tracking Status
firefox23 --- unaffected
firefox24 --- unaffected
firefox25 + fixed
firefox-esr17 --- unaffected
b2g18 --- unaffected

People

(Reporter: gkw, Assigned: bbouvier)

References

Details

(Keywords: crash, regression, testcase, Whiteboard: [jsbugmon:update])

Crash Data

Attachments

(2 files, 1 obsolete file)

Attached file stack
x = {} x.toString = (function(stdlib, n, heap) { "use asm" var imul = stdlib.Math.imul var Float32ArrayView = new stdlib.Float32Array(heap) function f() { return +(+0 * Float32ArrayView[(imul(-800, 0xf8ba1243) | 0) % (7 | 0xffffffff) >> 2]) } return f })(this, {}, ArrayBuffer(4096)) x + '' crashes js opt shell on m-c changeset 3fc610532baf with --no-ti --no-ion --no-baseline at js::Invoke and crashes js debug shell at js::CallJSNative Locking s-s just-in-case, autoBisect is running now. Setting needinfo from Benjamin since Luke seems to be away for awhile.
Flags: needinfo?(bbouvier)
I can reproduce on Mac as well, hitting this: Program received signal EXC_ARITHMETIC, Arithmetic exception.
OS: Windows 7 → All
Whiteboard: [jsbugmon:update] → [jsbugmon:update,bisect]
Crash Signature: [@ js::Invoke] [@ js::CallJSNative] → [@ js::Invoke] [@ js::CallJSNative]
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:update]
JSBugMon: Bisection requested, result: autoBisect shows this is probably related to the following changeset: The first bad revision is: changeset: http://hg.mozilla.org/mozilla-central/rev/f1088655c731 user: Jan de Mooij date: Tue Jul 09 10:23:58 2013 +0200 summary: Bug 864400 - Optimize ModI for non-constant power-of-2 divisors. r=h4writer This iteration took 337.518 seconds to run.
jandem, is bug 864400 a possible regressor?
Blocks: 864400
Crash Signature: [@ js::Invoke] [@ js::CallJSNative] → [@ js::Invoke] [@ js::CallJSNative]
Flags: needinfo?(jdemooij)
Currently investigating. Reduced the test case to function a(stdlib) { "use asm"; var imul = stdlib.Math.imul; function f() { return ((imul(-800, 0xf8ba1243)|0) % -1)|0; } return f; } var f = a(this) f() It appears that the code gen doesn't generate the negative test part as the range for RHS is +infinite, while RHS == -1. Weird.
Flags: needinfo?(bbouvier)
Attached patch proposed fix + test case (obsolete) — Splinter Review
(In reply to Benjamin Bouvier [:bbouvier] from comment #4) > It appears that the code gen doesn't generate the negative test part as the > range for RHS is +infinite, while RHS == -1. Weird. Actually, the code gen part didn't generate the negative test part for LHS, not RHS. But RHS is also negative, as it's a truncated integer multiplication. The negative test isn't generated as the range for LHS is positive (actually +Infinity), and the reason for that is that the range analysis didn't take into account the fact that the multiplication is truncated. In this case, if we overflow the range of int32, we can't tell in which direction the overflow will happen and hence we can't determine the range any more.
Assignee: general → bbouvier
Status: NEW → ASSIGNED
Attachment #774353 - Flags: review?(nicolas.b.pierron)
Flags: needinfo?(jdemooij)
Comment on attachment 774353 [details] [diff] [review] proposed fix + test case Review of attachment 774353 [details] [diff] [review]: ----------------------------------------------------------------- ::: js/src/ion/RangeAnalysis.cpp @@ +941,5 @@ > canBeNegativeZero_ = Range::negativeZeroMul(&left, &right); > setRange(Range::mul(&left, &right)); > + > + // Truncated multiplications could overflow in both directions > + if (isTruncated() && (range()->isUpperInfinite() || range()->isLowerInfinite())) if (isTruncated && !range->isInt32()) @@ +942,5 @@ > setRange(Range::mul(&left, &right)); > + > + // Truncated multiplications could overflow in both directions > + if (isTruncated() && (range()->isUpperInfinite() || range()->isLowerInfinite())) > + setRange(NULL); I think it would be sane if computeRange would at least compute a Range, even if we can infer it directly from the return type of the multiplication.
Attachment #774353 - Flags: review?(nicolas.b.pierron)
Thanks for the shorter method in the test! Also, I added a full int32 range for this particular case.
Attachment #774353 - Attachment is obsolete: true
Attachment #774414 - Flags: review?(nicolas.b.pierron)
Attachment #774414 - Flags: review?(nicolas.b.pierron) → review+
Thanks for fixing this, Benjamin! So this is not a regression from bug 864400 but it uncovered an older bug. On beta and aurora, MMul::computeRange() returns early if isTruncated(), so we don't have to uplift this.
Regression from bug 889451.
Blocks: 889451
No longer blocks: 864400
Status: ASSIGNED → RESOLVED
Closed: 11 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Target Milestone: --- → mozilla25
Status: RESOLVED → VERIFIED
Crash Signature: [@ js::Invoke] [@ js::CallJSNative] → [@ js::Invoke] [@ js::CallJSNative]
JSBugMon: This bug has been automatically verified fixed.
Crash Signature: [@ js::Invoke] [@ js::CallJSNative] → [@ js::Invoke] [@ js::CallJSNative]
Group: core-security
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: