emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.8k stars 3.31k forks source link

open(fname, O_RDONLY) fails with EINVALID #3678

Closed jbaicoianu closed 9 years ago

jbaicoianu commented 9 years ago

I'm trying to compile MAME with the latest version of Emscripten (incoming branch), and I'm getting EINVALID whenever I try to call open() on an existing file. Compiling with -s SYSCALL_DEBUG=1 shows this error:

syscall! 5,SYS_open
    (raw: "672")
    (str: "/mnt/myfile.zip")
    (raw: "32768")
    (raw: "0")
error: syscall failed with 22 (Invalid argument)
syscall return: -22

I've isolated this into a bare-bones test case and see the same error there:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
  char *fname = "/mnt/myfile.zip";
  printf("Opening file: %s\n", fname);
  int fd = open(fname, O_RDONLY);
  if (fd > 0) {
    printf("cool it worked, close it (fd=%d)\n", fd);
    close(fd);
  } else {
    printf("ERROR (fd=%d)\n", fd);
  }
  return 0;
}

Compile with: emcc opentest.c -o opentest.bc && emcc -O3 opentest.bc -s SYSCALL_DEBUG=1 -o opentest.js

I can read the file in the browser just fine via the FS object:

> FS.readFile('/mnt/myfile.zip')
< Uint8Array[3261863]

The file definitely exists on the FS according to the asm.js code as well, because the error code is different if I try to access a nonexistent file (as expected):

syscall! 5,SYS_open
    (raw: "672")
    (str: "/mnt/nofile.zip")
    (raw: "32768")
    (raw: "0")
error: syscall failed with 2 (No such file or directory)
syscall return: -2

I tried using git bisect to figure out when the problem was introduced, the last successful compile with was Emscripten version 1.30.5 - but the amount of time needed to compile and test each time makes it very difficult to work through the bisect, so I gave up on that approach.

Any ideas what might have changed?

kripken commented 9 years ago

Maybe I'm missing something, but in the testcase, why should it succeed? /mnt/myfile.zip does not exist. It fails in a native build as well.

When I do --embed-file, it succeeds as expected.

I assume the file does exist in the full app when you run it? Then the question is if we can make a standalone testcase that does include the file, but fails unexpectedly.

jbaicoianu commented 9 years ago

You're right, it works when I embed the file directly. I forgot to mention in the bug report that I'm using BrowserFS, so it looks like this may be a problem with the interface between BrowserFS and Emscripten.

jbaicoianu commented 9 years ago

Fixed in BrowserFS