Running AudioWorklet with Disable Cache set to true freezes then crashes browser
Categories
(Core :: Web Audio, defect)
Tracking
()
People
(Reporter: guest271314, Unassigned)
Details
Attachments
(6 files)
User Agent: Mozilla/5.0 (X11; Linux i686; rv:77.0) Gecko/20100101 Firefox/77.0
Steps to reproduce:
Set Disable Cache to true at Network tab of Developer Tools.
Run AudioWorklet code.
Actual results:
Audio is output until eventually the browser freezes and crashes.
A crash report was submitted yesterday.
Attempted to take screenshots and use getDisplayMedia() at Firefox to capture thee event, however the native screenshot application began to fail and due to Nightly no longer loading Blob URL's at top level the first attempt to record the screen was not achieved. By the time attempted to record a second time the browser had crashed, and eventually had to re-install the OS.
Expected results:
Setting Disable Cache at Network tab at Developer Tools should not freeze or crash the browser when AudioWorklet is run.
Comment 1•4 years ago
|
||
(In reply to guest271314 from comment #0)
A crash report was submitted yesterday.
Can you give the link to the crash, that you can find in about:crashes
? Thanks.
Reporter | ||
Comment 2•4 years ago
|
||
(In reply to Paul Adenot (:padenot) from comment #1)
(In reply to guest271314 from comment #0)
A crash report was submitted yesterday.
Can you give the link to the crash, that you can find in
about:crashes
? Thanks.
Unfortunately, no. There was a perfect storm of Firefox and Nightly issues that occurred.
Ran the code AudioWorklet at Nightly 77.
When initially ran the code observed a gap of silence precisely when ReadableStream
from fetch()
had completed in main thread as described at https://github.com/WebAudio/web-audio-api-v2/issues/73#issuecomment-612541949
At Nightly 77 had to adjust the number of 2 channel 128 Float32Arrays to set at Map before playback from 64 to 1024 to store only enough input data before starting playback with resume() avoid process() being called exactly between last read of Map and onmessage event; and remove import from Worker which is not currently supported, gaps in playback are observable intermitently throughout playback, with a several second gap of silence (was not sure browser and OS did not freeze) in playback before readable close 0 2 was posted to console when ReadableStream in Worker read() done value set to true. Less gaps in playback and no glitches once ReadableStream in Worker completed reading and transferring data to the AudioWorkletProcessor
Did not spare Nightly testing with Cache disabled, as Chromium behaviour is observably different when AudioWorklet is run for the first time and a fetch()
call is involved in any way and when Cache is disabled.
In this case initially considered the gap when cache was disabled the same as described above, the few seconds of silence would subside and processing would continue. That did not happen. Then attempted to capture the crash using Firefox 74. During this same time the OS itself is alerting of crash to send.
That is when encountered the perfect storm of bugs
- Was actually above to record the frozen window using
getDisplayMedia()
the first run ofMediaRecorder
. Usually just log the Blob URL in console, navigate to new tab, play then download. However, Nightly has a bug that does not load Blob URL's in address bar https://bugzilla.mozilla.org/show_bug.cgi?id=1626573, so missing first and what would turn out to be only change to visually capture the crash, as native screenshot application stopped working as well. - Did have time to notice a crash report was sent to Mozilla - however with 74 build instead of 77. That could have been about
getDisplayMedia()
was crashing https://bugzilla.mozilla.org/show_bug.cgi?id=1549095#c21, however, do not recollect exactly if the Nightly version was using was originally a 74 build that was updated to 77. Did not have time to investigate further, as the browser crashed and eventually just re-installed the OS - as do not infrequently due to the experimentation and tests that perform regularly ranging over a variety of APIs.
Am certain the crash report was transmitted to Mozilla on the same day that wrote https://github.com/WebAudio/web-audio-api-v2/issues/73#issuecomment-612552193
Cannot entirely exclude getDisplayMedia()
from being the cause of the crash. Also, cannot exclude AudioWorklet being the cause of the crash.
Can definitely convey that Disable Cache directly impacts AudioWorklet audio output, as it does at Chromium in a different way.
Nightly 77 crashes the browser when cache is disabled using the same code without cache disabled does not crash the browser.
though cannot identify it exactly.
It should be possible to reproduce the crash. Was able to save most of the test cases that was running that day externally. And all that is necessary is to Disable Cache in Developer Tools. Will just need to store the current ongoing tests and experiments that have running in preparation for crash and eventually re-installation of the OS.
Will modify https://plnkr.co/edit/nECtUZ?preview again to remove pipeTo() and transferring ReadableStream so that you can run with Cache Disable to observe the result yourself, if you are not able to reproduce gaps of silence with Cache Disabled for AudioWorklet code that you have locally. Would it help to have a complete example for you to run?
Reporter | ||
Comment 3•4 years ago
|
||
getDisplayMedia()
can freeze and crash the entire OS. Nightly 77 had frozen the browser before called getDisplayMedia()
from Firefox 74. So, can exclude getDisplayMedia()
usage at Firefox 74 from being the cause of the frozen Nightly 77 tab (unable to perform a user action at the tab; unresponsive) - when Disable Cache was set to true. From that regard the two outputs are differentiated. In theory the silence gap should be reproducible - without crashing the browser - by simply setting Disable Cache to true at Developer Tools and performing a fetch()
or other network request where the data retrieved is transferred to AudioWorklet
thread with postMessage()
. Would we need to coordinate in order to identify the specific crash report that could be sent when do carry out all of the steps that crashed the browser and OS previously for you to identify the report, if it gets through? Could probably start getDisplayMedia()
before take the necessary steps and transmit the data externally which should be observable up until the browser and/or OS crashes.
How do you want to proceed with reproducing frozen tab and crash for you to verify?
Comment 4•4 years ago
|
||
If the crash has been sent, then it's in the system. However I don't see crashes on AudioWorklet, appart from a couple crashes we know about, so it must be something else.
Running Firefox like so:
MOZ_DISABLE_CONTENT_SANDBOX=1 MOZ_LOG=MediaTrackGraph:5 ./firefox
should produce enough log to start diagnosing.
Reporter | ||
Comment 5•4 years ago
|
||
Ok. Will launch with that flag and attempt to reproduce what is described in this bug.
Reporter | ||
Comment 6•4 years ago
|
||
#4 Again, the tab at Nightly 77 where AudioWorklet
was being used was unresponsive before tried to capture the frozen tab with Firefox 74.
Reporter | ||
Comment 7•4 years ago
|
||
#4 Actually did preserve a version of the code that can run to reproduce the issue before the OS crashed https://github.com/WebAudio/web-audio-api-v2/files/4465663/AudioWorklet_MessagePort.zip. Disable Cache and run. Tested at *nix, where at least a gap of silence is observable when last tested.
Reporter | ||
Comment 8•4 years ago
|
||
#4
Where is the generated log file saved to?
Is there a way to use flags for that command before firefox executable instead of having to run a shell?
Reporter | ||
Comment 9•4 years ago
|
||
Trying to run the files in the attached and linked .zip
file at file: protocol also crashes the tab. Occurred twice within the last 10 minutes.
Reporter | ||
Comment 10•4 years ago
|
||
That crash was apparently due to running the linked code with Audio Blocked at Preferences.
Reporter | ||
Comment 11•4 years ago
|
||
When running the code at file: protocol after with audio and video not blocked after silence
uncaught exception: out of memory
is thrown 7 times.
Reporter | ||
Comment 12•4 years ago
|
||
Reporter | ||
Comment 13•4 years ago
|
||
Comment 14•4 years ago
|
||
Those crashes are because you're running with a version of Firefox that has been compiled with explicit disabling of AudioWorklet, see the line MOZ_CRASH Reason
.
Reporter | ||
Comment 15•4 years ago
|
||
That does not explain the silence before uncaught exception: out of memory
error at Nightly 77 when running the code at https://bugzilla.mozilla.org/attachment.cgi?id=9140037 with Disable Cache set at *nix.
Reporter | ||
Comment 16•4 years ago
|
||
Three more crashes
https://crash-stats.mozilla.org/report/index/c4586315-69f7-4547-b52c-074470200416
https://crash-stats.mozilla.org/report/index/7388a9c4-4a8c-4363-b0be-1f59d0200416
https://crash-stats.mozilla.org/report/index/560190e5-30c9-43b7-a9e4-d3a700200416
First silence is output, then
this.buffers.size:1024 0 0 audioWorklet.js:19:15
process() first call 0 1055 audioWorklet.js:46:15
AudioContext.state:running ck92tockj00091u6q8a6ezfvt:20:28
346 1.0013605442176872 audioWorklet.js:41:15
GEThttps://unpkg.com/monaco-editor@0.20.0/min/vs/base/worker/workerMain.js
[HTTP/2 200 OK 357ms]
GEThttps://unpkg.com/monaco-editor@0.20.0/min/vs/language/html/htmlWorker.js
[HTTP/2 200 OK 60ms]
GEThttps://unpkg.com/monaco-editor@0.20.0/min/vs/base/worker/workerMain.js
[HTTP/2 200 OK 383ms]
GEThttps://unpkg.com/monaco-editor@0.20.0/min/vs/language/html/htmlWorker.js
[HTTP/2 200 OK 62ms]
uncaught exception: out of memory
Why is Nightly 77 listing Firefox 75 crashes even though --no-remote
is appended to launch command?
Reporter | ||
Comment 17•4 years ago
|
||
Should not Firefox 75 and Nightly 77 be capable of running independently from .mozilla when --no-remote
or -no-remote
are appended to launch command?
Reporter | ||
Comment 18•4 years ago
|
||
At Preferences at Nightly 77 only 17.9 MB is displayed as disk space usage when the out of memory message is logged at console
.
What is the canonical procedure to run Firefox without impacting Nightly in .mozilla directory (if that is the cause of out of memory error or Nightly 77 listing Firefox 75 crashes)?
Reporter | ||
Comment 19•4 years ago
|
||
Are these Nightly error messages?
Error: Module resolve hook not set self-hosted:1235:1
CallModuleResolveHook self-hosted:1235
InnerModuleInstantiation self-hosted:1438
declarationInstantiation self-hosted:1408
AbortError: The operation was aborted
Comment 20•4 years ago
|
||
Resetting severity to default of --
.
Comment 21•4 years ago
|
||
Bugbug thinks this bug should belong to this component, but please revert this change in case of error.
Comment 22•4 years ago
|
||
(In reply to guest271314 from comment #17)
Created attachment 9141005 [details]
Screenshot_2020-04-16_14-11-49.pngShould not Firefox 75 and Nightly 77 be capable of running independently from .mozilla when
--no-remote
or-no-remote
are appended to launch command?
Yes. -profile <a path to a directory> works:
./firefox --no-remote -profile /tmp/foo
for example. We fixed an OOM bug recently, please try again: https://bugzilla.mozilla.org/show_bug.cgi?id=1631713
Updated•4 years ago
|
Reporter | ||
Comment 23•4 years ago
|
||
Will test again later today. You can test for yourself (with and without cache disabled) at https://plnkr.co/edit/yh5A66UhMnlpq0JF?preview.
Reporter | ||
Comment 24•4 years ago
|
||
27:27 duration wav with user code that processes response from WAV to Float32Array in "real-time" could be cause of gaps and glitches.
If user code is part of reason for glitches is the case no gaps or glitches should occur when using an AudioNode (e.g., MediaElementAudioSourceNode, MediaStreamAudioSourceNode) connected to AudioWorkletNode for the same media?
Making sure Disable Cache is set at Network tab at Developer Tools, reload plnkr, not top window, first run gaps or glitches +/-10 seconds to copy/paste line from console Included console.log() in the code to check if there is any difference with or without a user defined function being executed every second, or if a difference can be conclusively determined to be any single or set of variables on when AudioWorklet is processing.
First run https://plnkr.co/edit/yh5A66UhMnlpq0JF?preview
process() executions per second, second, minute
344 96 1.6
344 152.00072562358275 2.5333454270597127
345 219.00190476190477 3.650031746031746
344 220.00036281179138 3.6666727135298562
344 280.00072562358275 4.6666787603930455
344 342.00090702947847 5.7000151171579745
345 407.00226757369614 6.783371126228269
345 499.0026303854875 8.316710506424792 // when checking Network tab at Developer Tools to make sure Disable Cache is checked, select "Disable Cache" with mouse to copy/paste; Nightly notification to update; verifiable or untestable?
345 593.0028117913832 9.883380196523055
344 713.0006349206349 11.883343915343914
345 878.0016326530613 14.633360544217688
11 total observable gaps or glitches.
Restart Nightly to exclude that variable.
In theory, there should be no gaps or glitches when using MediaElementAudioSourceNode connected to AudioWorkletNode playing same media resource.
First run https://plnkr.co/edit/vLwcze?preview
[object AudioWorkletGlobalScope] bypass-processor.js:12:9
undefined undefined bypass-processor.js:21:26
TypeError: can't convert undefined to object bypass-processor.js:25:23
21 globalThis.console.log(input[0], input[1]);
25 output[channel].set(input[channel]);
No audio is output.
Those are the facts, here, at *nix 32 bit, Nightly 77.
Certainly the requirement is no gaps or glitches or undefined.
Will continue testing.
Reporter | ||
Comment 25•4 years ago
|
||
Reporter | ||
Comment 26•4 years ago
|
||
To avoid cross-origin as reason for 0's leading to undefined in AudioWorklet used local file. The file only played half out of at least 10 attempts. undefined is still logged at console (for inputs) even when the file plays.
[object AudioWorkletGlobalScope] bypass-processor.js:12:9
undefined undefined bypass-processor.js:21:26
TypeError: can't convert undefined to object bypass-processor.js:25:23
[object AudioWorkletGlobalScope] bypass-processor.js:12:9
Float32Array(128) [ 2.2689395251518363e-8, -3.061248676772266e-8, -9.409515655534051e-8, -1.465996746219389e-7, -1.6448520057110727e-7, -1.3010776456212625e-7, -4.11371061659338e-8, 2.785993302723e-8, 1.0130912642125622e-7, 1.5758504900986736e-7, … ]
undefined bypass-processor.js:21:26
TypeError: can't convert undefined to object
<!DOCTYPE html>
<html>
<head>
<title>
MediaElementAudioSourceNode connected to AudioWorklet does not glitch at
*nix (when latencyHint is set to 1.0)
</title>
</head>
<body>
<input type="file" accept=".wav" />
<audio controls autoplay></audio>
<script>
const input = document.querySelector('input[type=file]');
const context = new AudioContext();
input.onchange = async e => {
await context.suspend();
const mediaElement = document.querySelector('audio');
mediaElement.onloadedmetadata = async _ =>
await context.resume();
const source = new MediaElementAudioSourceNode(context, {
mediaElement,
});
await context.audioWorklet.addModule('bypass-processor.js');
const bypasser = new AudioWorkletNode(context, 'bypass-processor');
source.connect(bypasser);
bypasser.connect(context.destination);
mediaElement.src = URL.createObjectURL(e.target.files[0]);
};
</script>
</body>
</html>
Reporter | ||
Comment 27•4 years ago
|
||
Substituted onplay
for onmetadata
and removed suspend()
and resume()
calls, changed accept at input element to accept audio/,video/, using original WAV file converted to Opus in WebM container, where the file does not play and logged cannot decode media resource warning, and undefined is still resulting in error in AudioWorkletProcessor. bugzilla does not allow upload of the single 19.7 MB WebM file, a copy of the original https://drive.google.com/file/d/1Hyz3Nb4ujhe1bEBuT6n-Rb93VoMCC9eg/view.
$ mkvmerge -J Deltanine121113Pt3Wav.webm
{
"attachments": [],
"chapters": [],
"container": {
"properties": {
"container_type": 17,
"is_providing_timestamps": true,
"muxing_application": "Chrome",
"writing_application": "Chrome"
},
"recognized": true,
"supported": true,
"type": "Matroska"
},
"errors": [],
"file_name": "Deltanine121113Pt3Wav.webm",
"global_tags": [],
"identification_format_version": 12,
"track_tags": [],
"tracks": [
{
"codec": "Opus",
"id": 0,
"properties": {
"audio_bits_per_sample": 32,
"audio_channels": 2,
"audio_sampling_frequency": 48000,
"codec_id": "A_OPUS",
"codec_private_data": "4f707573486561640102000080bb0000000000",
"codec_private_length": 19,
"default_track": true,
"enabled_track": true,
"forced_track": false,
"language": "eng",
"minimum_timestamp": 0,
"number": 1,
"uid": 40724061936670366
},
"type": "audio"
}
],
"warnings": []
}
TypeError: can't convert undefined to object 4 bypass-processor.js:25:23
[object AudioWorkletGlobalScope] bypass-processor.js:12:9
Float32Array(128) [ -7.95498706519323e-21, -2.153211622057824e-19, -5.716999350053724e-19, -3.5438898983609365e-19, -1.3173380650499e-18, 8.425843699199902e-19, 2.0662839352676623e-18, 7.512917544349627e-18, 1.564502940803195e-17, 2.086260677933063e-17, … ]
Float32Array(128) [ 1.1394594691470519e-20, 1.854052964734013e-20, 4.385243087487324e-20, 1.4464648877773372e-19, -5.231389012781632e-19, 5.003439749453097e-19, 1.8632026162846153e-19, 9.842857855243054e-19, -2.0402409808620428e-19, -3.635715218160448e-18, … ]
bypass-processor.js:21:26
TypeError: can't convert undefined to object
Float32Array(128) [ 0.00012676289770752192, 0.000029341032131924294, -0.000020385026800795458, -0.0000356335767719429, -0.00021798073430545628, -0.0001800551835913211, -0.0001801458711270243, -0.0002827983698807657, -0.0002620148297864944, -0.0002717776515055448, … ]
Float32Array(128) [ 0.00012676289770752192, 0.000029341032131924294, -0.000020385026800795458, -0.0000356335767719429, -0.00021798073430545628, -0.0001800551835913211, -0.0001801458711270243, -0.0002827983698807657, -0.0002620148297864944, -0.0002717776515055448, … ]
bypass-processor.js:21:26
TypeError: can't convert undefined to object
[object AudioWorkletGlobalScope] bypass-processor.js:12:9
Float32Array(128) [ -0.00003955262582167052, -0.000039763344830134884, -0.0000400975150114391, -0.00004020964843221009, -0.00004051901487400755, -0.000040675287891644984, -0.00004081758743268438, -0.000041065843106480315, -0.0000411241126130335, -0.000041284525650553405, … ]
Float32Array(128) [ -0.00003955262582167052, -0.000039763344830134884, -0.0000400975150114391, -0.00004020964843221009, -0.00004051901487400755, -0.000040675287891644984, -0.00004081758743268438, -0.000041065843106480315, -0.0000411241126130335, -0.000041284525650553405, … ]
bypass-processor.js:21:26
TypeError: can't convert undefined to object
Media resource blob:https://run.plnkr.co/26c2c3b0-440d-4bde-a260-532d89d4ee59 could not be decoded. 10 ck9tdnzhd00061u6pkepau9bb
Media resource blob:https://run.plnkr.co/26c2c3b0-440d-4bde-a260-532d89d4ee59 could not be decoded, error: Error Code: NS_ERROR_DOM_MEDIA_DEMUXER_ERR (0x806e000c) ck9tdnzhd00061u6pkepau9bb
[object AudioWorkletGlobalScope] bypass-processor.js:12:9
Float32Array(128) [ -0.0008568908087909222, -0.0007726798066869378, -0.0006592735880985856, -0.0004877644532825798, -0.00019008928211405873, 0.00007043153891572729, 0.00042501118150539696, 0.0007395012071356177, 0.000886920839548111, 0.0010314173996448517, … ]
Float32Array(128) [ -0.0008568908087909222, -0.0007726798066869378, -0.0006592735880985856, -0.0004877644532825798, -0.00019008928211405873, 0.00007043153891572729, 0.00042501118150539696, 0.0007395012071356177, 0.000886920839548111, 0.0010314173996448517, … ]
bypass-processor.js:21:26
TypeError: can't convert undefined to object bypass-processor.js:25:23
Reporter | ||
Comment 28•4 years ago
|
||
Compare plnkr transferring a single ReadableStream
to AudioWorkletProcessor
https://plnkr.co/plunk/nECtUZ, instead of transferring 500,000 Float32Array's https://run.plnkr.co/preview/ck9ti8hxi00081u6l4modpj6z/ (Chromium also outputs gaps and glitches when posting thousands of messages) at Chrome or Chromium with --enable-experimental-web-platform-features flag to transfer streams with postMessage()
. Some glitches, no gaps, with process()
beginning when 64x2 Float32Array's are set in Map, reading the stream "at the same time" in a method, can throw error when process()
catches the case of "collision" if Map.size === 0, during read of the stream, handled by returning true until the next process() call where the read has by then accumulated data in Map.
AudioWorklet at Nightly does not playback, or does not playback without gaps or glitches for different cases.
Disable Cache with AudioWorklet is not crashing the browser at Nightly 78.
Reporter | ||
Comment 29•4 years ago
|
||
Dry run test transferring one ReadableStream
at Chromium has at least 1 gap, an observable second of silent output where there should be audio output of media resource, with or without cache disabled, consistently.
Comment 30•4 years ago
|
||
Because this bug's Severity has not been changed from the default since it was filed, and it's Priority is --
(Backlog,) indicating it has has not been previously triaged, the bug's Severity is being updated to --
(default, untriaged.)
Reporter | ||
Comment 31•4 years ago
|
||
The one observable gap at Chromium 81 when transferring a ReadableStream
is at the completion of reading and writing the stream, after network request already completed
readable close 724.4625850340136 31948800 317598 0 2
audioWorklet.js:115 read/write done 724.4625850340136 31948800 317599 0 0
The issue appears to be potential for certain code outside of process()
to affect process, or in any event audio output observable in form of a gap of silence, not a glitch without gap of silence. Not sure how that would be possible to solve in a specification, or re the ssource code which might have a given "priority" flag set. Using the approach of TransformStream
reduces the variable to one (at last bytes processed) from multiple unknown points during the playback (of same track) when transferring thousands of Float32Array
objects with postMessage()
which is not reliable for live streaming without gaps.
Reporter | ||
Comment 32•4 years ago
|
||
The crash was caused by getDisplayMedia()
trying to capture the window AudioWorketlet
was running in. The remainder of the comments in this issue provide details of observations experimenting with different approaches for a potentially infinite input media stream from N fetch()
calls to AudioWorklet
. Thus, closing this issue as invalid.
Reporter | ||
Updated•4 years ago
|
Description
•