Closed Bug 1629384 Opened 4 years ago Closed 4 years ago

Running AudioWorklet with Disable Cache set to true freezes then crashes browser

Categories

(Core :: Web Audio, defect)

77 Branch
defect

Tracking

()

RESOLVED INVALID

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.

(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.

Flags: needinfo?(guest271314)

(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

  1. Was actually above to record the frozen window using getDisplayMedia() the first run of MediaRecorder. 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.
  2. 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?

Flags: needinfo?(guest271314)

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?

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.

Ok. Will launch with that flag and attempt to reproduce what is described in this bug.

#4 Again, the tab at Nightly 77 where AudioWorklet was being used was unresponsive before tried to capture the frozen tab with Firefox 74.

#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.

#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?

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.

That crash was apparently due to running the linked code with Audio Blocked at Preferences.

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.

Attached file 873779.fxsnapshot

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.

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.

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?

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?

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)?

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

Resetting severity to default of --.

Bugbug thinks this bug should belong to this component, but please revert this change in case of error.

Component: Untriaged → Web Audio
Product: Firefox → Core

(In reply to guest271314 from comment #17)

Created attachment 9141005 [details]
Screenshot_2020-04-16_14-11-49.png

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?

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

Flags: needinfo?(guest271314)

Will test again later today. You can test for yourself (with and without cache disabled) at https://plnkr.co/edit/yh5A66UhMnlpq0JF?preview.

Flags: needinfo?(guest271314)

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.

Attached audio pcm0808m.wav

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>

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

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.

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.

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.)

Severity: normal → --

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.

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.

Status: UNCONFIRMED → RESOLVED
Closed: 4 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: