WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
275160
REGRESSION (iOS 17.5): Method call silently fails since iOS 17.5/ MacOS 14.5 after a warmup period
https://bugs.webkit.org/show_bug.cgi?id=275160
Summary
REGRESSION (iOS 17.5): Method call silently fails since iOS 17.5/ MacOS 14.5 ...
Jekfer Bichon
Reported
2024-06-05 08:00:28 PDT
Created
attachment 471592
[details]
Sample to reproduce the issue Hello, We have discovered quite a vicious bug after we updated to iOS 17.5 and MacOS 14.5. As I cannot share proprietary code with you, I have created and attached a small sample, with some comments, where the problem is visible. In the sample, I have two loops to copy the contents of two typed arrays into a bigger typed array. In the first loop, I allow the index to go out of bound, in the 2nd loop, I don't. This code, after a warmup period, starts to fail silently, with the target typed array containing only 0s. The first few hundred iterations are working as expected. On other OSs and browsers, going out of bound returns the "undefined" value, that was also the case on iOS and MacOS before we updated to the latest versions. What I suspect is that the engine optimizes the code after warming up and that code seems to be unable to handle this situation. Worse, the 2nd loop where I don't allow the index to go out of bound also starts failing silently but if you comment the 1st loop, the 2nd one never fails. If you put a breakpoint inside the copying method, the whole code becomes functional for a short period of time before starting to fail again. This behavior makes the debugging process quite frustrating as trying to observe the issue makes the issue disappear. This behavior is a regression compared to previously released iOS and MacOS versions. Thanks.
Attachments
Sample to reproduce the issue
(3.58 KB, text/html)
2024-06-05 08:00 PDT
,
Jekfer Bichon
no flags
Details
View All
Add attachment
proposed patch, testcase, etc.
Radar WebKit Bug Importer
Comment 1
2024-06-05 14:09:52 PDT
<
rdar://problem/129303210
>
Ahmad Saleem
Comment 2
2024-06-05 20:12:37 PDT
It is happening on WebKit ToT (
279763@main
) as well.
Jarred Sumner
Comment 3
2024-06-06 02:00:54 PDT
Possibly caused by
https://bugs.webkit.org/show_bug.cgi?id=272107
, based on this diff between
https://github.com/oven-sh/WebKit/compare/autobuild-2475726ed0329ab2d2a92daf73e12ee1e485d575...autobuild-e3a2d89a0b1644cc8d5c245bd2ffee4d4bd6c1d5
This bug reproduces starting in Bun v1.1.2, and in the jsc shell. ``` ❯ bun-1.1.2 repero.js {"success":331,"fail":169} {"success":331,"fail":669} {"success":331,"fail":1169} {"success":331,"fail":1669} {"success":331,"fail":2169} {"success":331,"fail":2669} {"success":331,"fail":3169} {"success":331,"fail":3669} {"success":331,"fail":4169} {"success":331,"fail":4669} {"success":331,"fail":5169} {"success":331,"fail":5669} {"success":331,"fail":6169} {"success":331,"fail":6669} {"success":331,"fail":7169} {"success":331,"fail":7669} {"success":331,"fail":8169} {"success":331,"fail":8669} {"success":331,"fail":9169} ``` ``` ❯ bun-1.1.1 repero.js {"success":500,"fail":0} {"success":1000,"fail":0} {"success":1500,"fail":0} {"success":2000,"fail":0} {"success":2500,"fail":0} {"success":3000,"fail":0} {"success":3500,"fail":0} {"success":4000,"fail":0} {"success":4500,"fail":0} {"success":5000,"fail":0} {"success":5500,"fail":0} {"success":6000,"fail":0} {"success":6500,"fail":0} {"success":7000,"fail":0} {"success":7500,"fail":0} {"success":8000,"fail":0} {"success":8500,"fail":0} {"success":9000,"fail":0} {"success":9500,"fail":0} ``` Code that runs in jsc shell and bun without safari: ``` globalThis.console ??= {}; console.log ??= print; var cb; globalThis.setInterval ||= function setInterval(cb, ms) { function iter() { setTimeout(iter, ms); cb && cb(); } setTimeout(iter, ms); }; setInterval(() => { cb && cb(); }, 16); function requestAnimationFrame(callback) { cb = callback; } function copyFromSrcToTgt({ count, size, srcBuffer, srcOffset, srcStride, tgtBuffer, tgtOffset, tgtStride, }) { const source_buffer = new Uint32Array(srcBuffer, srcOffset); const target_buffer = new Uint32Array(tgtBuffer, tgtOffset); for (let v = 0; v < count; v++) { const src_base = (v * srcStride) / 4; const tgt_base = (v * tgtStride) / 4; for (let k = 0; k < size / 4; k++) { target_buffer[tgt_base + k] = source_buffer[src_base + k]; } } } let buffersNotAligned = []; for (let i = 0; i < 500; i++) { let typedBuffer = new Float32Array(i % 2 === 0 ? 900 : 810); typedBuffer.fill(i + 1); buffersNotAligned.push(typedBuffer); } let buffersAligned = []; for (let i = 0; i < 500; i++) { let typedBuffer = new Float32Array(900); typedBuffer.fill(i + 1); buffersAligned.push(typedBuffer); } let success = 0; let fail = 0; function doCopyOperation(buffers) { for (let i = 0; i < buffers.length; i += 2) { let buffer1 = buffers[i]; let buffer2 = buffers[i + 1]; let dstBuffer = new Float32Array( 2 * Math.max(buffer1.length, buffer2.length) ); copyFromSrcToTgt({ count: buffer1.length / 3, size: 3 * 4, // byte size of 3 float 32 srcBuffer: buffer1.buffer, tgtBuffer: dstBuffer.buffer, srcOffset: 0, srcStride: 12, tgtOffset: 0, tgtStride: 24, }); copyFromSrcToTgt({ // This is a deliberate mistake so that we can go out of bound for buffer2, which should yield undefined values // using buffer2.length instead fixes the problem but the sample has been made to showcase the issue // Going out of bound works fine on Win, Linux and Android, was also working fine on MacOS before 14.5 and iOS before 17.5 // It also works fine on current MacOS and iOS for a period count: buffer1.length / 3, size: 3 * 4, // byte size of 3 float 32 srcBuffer: buffer2.buffer, tgtBuffer: dstBuffer.buffer, srcOffset: 0, srcStride: 12, tgtOffset: 12, tgtStride: 24, }); if (dstBuffer[0] === 0) { fail++; } else { success++; } } } function doOperation() { // This fails after a warm up period doCopyOperation(buffersNotAligned); // This should always work, but also starts failing after a warm up period, if the previous line is commented, this never fails doCopyOperation(buffersAligned); console.log( JSON.stringify({ success, fail, }) ); if (success > 1e6 || fail > 1e6) { return; } requestAnimationFrame(doOperation); } requestAnimationFrame(doOperation); ```
Yusuke Suzuki
Comment 4
2024-06-06 14:03:06 PDT
Pull request:
https://github.com/WebKit/WebKit/pull/29590
EWS
Comment 5
2024-06-06 20:01:35 PDT
Committed
279790@main
(8f9d6d2b9c5f): <
https://commits.webkit.org/279790@main
> Reviewed commits have been landed. Closing PR #29590 and removing active labels.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug