Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
Ask Question
I try to load a file from my local filesystem, which is then loaded into MEMFS (provided by Emscripten) and pass the file name as one argument to a C program which is cross compiled as WebAssembly using Emscripten. When calling the function to load the file I get the error: Uncaught RuntimeError: memory access out of bounds.
What am I doing wrong? Are the parameters handed-over incorrectly or is the file access not correct?
C program, has standard main and parameters are passed correctly, loading the file looks like this (in an abstract):
int CLASS main(int argc, const char **argv)
FILE *ifp;
const char *ifname;
// Start - debug code
for (int i = 0; i < argc; i++)
// ==> This prints the arguments correctly in the browser console, so the hand-over works.
printf("argv[%d] = %s\n", i, argv[i]);
char cwd[1024];
if (getcwd(cwd, sizeof(cwd)) != NULL)
// Also prints the MEMFS directory structure correctly.
printf("Current working directory: %s\n", cwd);
// End - debug code
ifname = argv[arg];
if (!(ifp = fopen(ifname, "rb")))
perror(ifname);
continue;
In JavaScript it's called like this:
async _runProgram(args) {
// Load the emscripten wrapper
this._dcrawModule = await Module();
// Convert the JavaScript array to a C-style null-terminated string array
const paramStrings = args.map((str) => this._dcrawModule.allocateUTF8(str));
// Allocate memory for the array of pointers
const paramArray = this._dcrawModule.stackAlloc((paramStrings.length + 1) * 4);
paramStrings.forEach((strPtr, i) => {
this._dcrawModule.setValue(paramArray + i * 4, strPtr, 'i32');
// Null-terminate the array
this._dcrawModule.setValue(paramArray + paramStrings.length * 4, 0, 'i32');
// Call the `_main` method with the parameter array
return this._dcrawModule['_main'](paramStrings.length + 1, paramArray, 0);
The file itself is loaded into MEMFS doing the following and then the '_runProgram' function is called:
// Create a workspace directory in the emscripten virtual file system and go to it
FS.mkdir('/workspace');
FS.chdir('/workspace');
if (raw_file) {
FS.createDataFile('/workspace/', 'raw_buf', raw_file, true, true);
args.push('/workspace/raw_buf');
//args.push('raw_buf'); //Tried also this and other variants, no success.
this._runProgram(args);
Does anyone has experience with Emscripten, MEMFS, WebAssembly and opening a file in a C-program?
My preference would be to not change the C-program as this is not mine and I want to avoid having to adapt it every time it might be updated in the future (in addition my C knowledge is quite limited :-P)
(full c program can be found here: https://dechifro.org/dcraw/dcraw.c)
Flags used to run the emcc compiler are the following:
FLAGS = -O0 \
-s ALLOW_MEMORY_GROWTH=1 \
-s TOTAL_MEMORY=134217728 \
-s NO_EXIT_RUNTIME=1 \
-s FORCE_FILESYSTEM=1 \
--memory-init-file 0 \
-s MODULARIZE=1 \
-s WASM=1 \
-s EXPORT_ES6=1 \
-s EXPORTED_FUNCTIONS="['_main']" \
-s EXPORTED_RUNTIME_METHODS=FS,setValue,stringToUTF8,allocateUTF8,stackAlloc \
-DNODEPS=1
–
–
–
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.