emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.79k stars 3.3k forks source link

pThreads: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed. #14089

Closed jeffRTC closed 5 months ago

jeffRTC commented 3 years ago

This line var objectUrl = URL.createObjectURL(e.data.urlOrBlob); in the worker file generated by Emscripten cause this error on my browser (Chrome). I don't know the exact reason for this.

I compiled with -s USE_PTHREADS=1 and -s PTHREAD_POOL_SIZE=1

TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed.
    at onmessage (21a7629e-a9c7-4d58-881c-c0098fb9b224:63)
threadPrintErr @ 21a7629e-a9c7-4d58-881c-c0098fb9b224:22
onmessage @ 21a7629e-a9c7-4d58-881c-c0098fb9b224:179

The worker file is inlined but I don't think that causing this issue.

jeffRTC commented 3 years ago

@kripken @sbc100

I logged

        console.log(typeof e.data.urlOrBlob)
        console.log(e.data.urlOrBlob)

Both of them returns undefined.

Why they are undefined? What's the error?

jeffRTC commented 3 years ago

I'm willing to bet that this part is broken somehow maybe because I have everything in single file??

worker.postMessage({
   "cmd": "load",
   "urlOrBlob": Module["mainScriptUrlOrBlob"] || _scriptDir,
   "wasmMemory": wasmMemory,
   "wasmModule": wasmModule
});
jeffRTC commented 3 years ago

Found this, https://stackoverflow.com/questions/63698319/the-module-variables-mechanism-in-emscripten-while-compiling-pthread-to-worke and this comment,

  // If the application main .js file was loaded from a Blob, then it is not possible
  // to access the URL of the current script that could be passed to a Web Worker so that
  // it could load up the same file. In that case, developer must either deliver the Blob
  // object in Module['mainScriptUrlOrBlob'], or a URL to it, so that pthread Workers can
  // independently load up the same main application file.
  'urlOrBlob': Module['mainScriptUrlOrBlob'] || _scriptDir,

I'm not sure what should I do. Should I create a post processing script to copy the whole file again into Module['mainScriptUrlOrBlob'] as a blob? Why the compiler don't provide an option for this?

I have both worker and the main in same file but the whole file loaded via Blob ..

jeffRTC commented 3 years ago

Ahahaha I found existing thread on this (Thanks to Github Search),

https://github.com/emscripten-core/emscripten/issues/7562

Minimal action from emscripten:
At the very least emscripten should add an error telling that it can't find a url that points to the main module before sending it to the worker.

Maximum action from emscripten:
Finally provide non-hacked in support for properly exporting and loading ES6/commonjs modules (it is 2020 now after all...).
jeffRTC commented 3 years ago

I upgraded to the latest version but I still can't fix the damn thing...I am not sure what should I do ..

jeffRTC commented 3 years ago

I love this..

worker.js onmessage() captured an uncaught exception: ReferenceError: _scriptDir is not defined

The fix for this error is here in case anyone came across

https://github.com/tensorflow/tfjs/blob/38f8462fe642011ff1b7bcbb52e018f3451be58b/tfjs-backend-wasm/scripts/patch-threaded-simd-module.js

jeffRTC commented 3 years ago

Oh wow

https://github.com/emscripten-core/emscripten/pull/12832

@kripken You should merge this one. It fix a lot of things ....

kripken commented 3 years ago

I've never seen that Overload resolution failed error - maybe you can provide a testcase showing it?

The PR you mention was closed, and reading it now, I don't think it was needed, so I don't understand the last point either.

jeffRTC commented 3 years ago

I've never seen that Overload resolution failed error - maybe you can provide a testcase showing it?

The PR you mention was closed, and reading it now, I don't think it was needed, so I don't understand the last point either.

Overload resolution failed means that the URL.createObjectURL(e.data.urlOrBlob) received undefined value.

You can try this on Chrome console and you will see the error,

URL.createObjectURL(undefined)

The worker file has no checking for undefined values.

jeffRTC commented 3 years ago

If you Google this,

"emscripten Failed to execute 'createObjectURL' on 'URL': Overload resolution failed"

You will find a lot of posts seeking help (including this) to debug because the error is ambiguous

Alexufo commented 3 years ago

@jeffRTC Have you solved it?

jeffRTC commented 3 years ago

@Alexufo No, In my case, I gotten close to fixing this, but it turns out Emscripten lack test cases for std::future and dead locks..

Alexufo commented 3 years ago

@jeffRTC I solved it in my case. You have a wrong worker initialisation config I suppose. createObjectURL must be an url to js file (the same as you are loaded inside worker. engine_wasm.js in example ) for multi thread mode.

try it in your worker

importScripts("./engine_wasm.js");

const Lib = {
    locateFile: (file) => file,
    onRuntimeInitialized: () => {
        console.log('onRuntimenitialized');
    },
    mainScriptUrlOrBlob: "./engine_wasm.js",
};

// LibModule is the name of the exported library in engine_wasm.js
LibModule(Lib).then((engine) => {
    console.log(engine);
});

And you must compile with emcc -pthread -s PROXY_TO_PTHREAD example.c -o example.js

more info https://web.dev/webassembly-threads/

engineer1109 commented 2 years ago

template solved method:

change this code:

worker.postMessage({
                        "cmd": "load",
                        "urlOrBlob": Module["mainScriptUrlOrBlob"] || (self.location.origin + "/js/yourwasm.js"),
                        "wasmMemory": wasmMemory,
                        "wasmModule": wasmModule
                    })
jkanche commented 2 years ago

I am also running into this issue because I have a service-worker that is caching resources (this also allows me to enable CrossOriginIsolation & sharedArrayBuffers for pthreads).

The last solution from @engineer1109 works for me, but I would prefer not to change the generated js bindings. Is there a way to set the _scriptDir so its not undefined ?

Anandk0801 commented 5 months ago
  this.selectedMedia = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(event.target.files[0]))

console-----------ERROR TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed.

sbc100 commented 5 months ago

@Anandk0801 that doesn't looks like emscripten-related code.

As of #21701 we no longer need _scriptDir or createObjectURL in the pthread workers so I think we can mark this as fixed.