wac
wac copied to clipboard
examples cannot stat wasm files
running examples in README.md, and each one produces an error similar to:
> root@f2b8deabf964:/wac# ./wace examples_c/hello1.wasm
> Error(platform_libc.c:47): could stat file 'examples_c/hello1.wasm'
Please show how you built wace
and examples_c/hello1.wasm
. Perhaps you did make clean
before trying to run the example and the wasm file is missing?
I am able to build and run the example successfully:
~/wac $ docker run -v `pwd`:/wac -w /wac -it kanaka/emscripten bash
root@1647e5c1fff2:/wac# make wace
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c wace_emscripten.c -o wace_emscripten.o
...
root@1647e5c1fff2:/wac# make examples_c/hello1.wasm
emcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -s WASM=1 -s SIDE_MODULE=1 -s LEGALIZE_JS_FFI=0 -I examples_c/include -s USE_SDL=2 examples_c/hello1.c -o examples_c/hello1.wasm
root@1647e5c1fff2:/wac# ./wace examples_c/hello1.wasm
hello world
13:26 $ docker run -v `pwd`:/wac -w /wac -it kanaka/emscripten bash
root@f06b7bc1091e:/wac# make clean
rm -f *.o *.a *.d wac wace wace-sdl.c \
lib/*.o lib/*.d kernel/*.o kernel/*.d \
examples_c/*.js examples_c/*.html \
examples_c/*.wasm examples_c/*.wast \
examples_wast/*.wasm
root@f06b7bc1091e:/wac# make wac
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c wa.c -o wa.o
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c util.c -o util.o
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c thunk.c -o thunk.o
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c platform_libc.c -o platform_libc.o
ar rcs wa.a wa.o util.o thunk.o platform_libc.o
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c wac.c -o wac.o
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -rdynamic -Wl,--no-as-needed -o wac \
-Wl,--start-group wa.a wac.o -Wl,--end-group -lm -ldl -ledit
root@f06b7bc1091e:/wac# make examples_wast/arith.wasm
wasm-as examples_wast/arith.wast -o examples_wast/arith.wasm
root@f06b7bc1091e:/wac# ./wac examples_wast/arith.wasm add 2 3
Error(platform_libc.c:47): could stat file 'examples_wast/arith.wasm'
root@f06b7bc1091e:/wac#
Looking at the code I see that the failure you're seeing means that it was able to open the file, but it couldn't fstat it to get the module file size. My suspicion is something about the file-system or the permissions on your system is preventing the fstat from working. What OS are you running this on?
Also, here is a small patch that you can apply to get the fstat error number which would help diagnose what is happening:
diff --git a/platform_libc.c b/platform_libc.c
index 5e026a5..1706a3f 100644
--- a/platform_libc.c
+++ b/platform_libc.c
@@ -39,12 +39,14 @@ void *arecalloc(void *ptr, size_t old_nmemb, size_t nmemb,
// open and mmap a file
uint8_t *mmap_file(char *path, int *len) {
int fd;
+ int res;
struct stat sb;
uint8_t *bytes;
fd = open(path, O_RDONLY);
if (fd < 0) { FATAL("could not open file '%s'\n", path); }
- if (fstat(fd, &sb) < 0) { FATAL("could stat file '%s'\n", path); }
+ res = fstat(fd, &sb);
+ if (res < 0) { FATAL("could not stat file '%s' (%d)\n", path, res); }
bytes = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (len) {
I'm on MacOS 10.13.6 (High Sierra).
updated your patch. the actual errno is 75.
#define EPROGMISMATCH 75 /* Program version wrong */
diff --git a/platform_libc.c b/platform_libc.c
index 5e026a5..66b843c 100644
--- a/platform_libc.c
+++ b/platform_libc.c
@@ -5,6 +5,7 @@
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
+#include <sys/errno.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <dlfcn.h>
@@ -39,12 +40,14 @@ void *arecalloc(void *ptr, size_t old_nmemb, size_t nmemb,
// open and mmap a file
uint8_t *mmap_file(char *path, int *len) {
int fd;
+ int res;
struct stat sb;
uint8_t *bytes;
fd = open(path, O_RDONLY);
if (fd < 0) { FATAL("could not open file '%s'\n", path); }
- if (fstat(fd, &sb) < 0) { FATAL("could stat file '%s'\n", path); }
+ res = fstat(fd, &sb);
+ if (res < 0) { FATAL("could not stat file '%s' (%d)\n", path, errno); }
bytes = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (len) {
root@126379a5d272:/wac# make clean
rm -f *.o *.a *.d wac wace wace-sdl.c \
lib/*.o lib/*.d kernel/*.o kernel/*.d \
examples_c/*.js examples_c/*.html \
examples_c/*.wasm examples_c/*.wast \
examples_wast/*.wasm
root@126379a5d272:/wac# make wac
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c wa.c -o wa.o
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c util.c -o util.o
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c thunk.c -o thunk.o
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c platform_libc.c -o platform_libc.o
ar rcs wa.a wa.o util.o thunk.o platform_libc.o
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -c wac.c -o wac.o
gcc -O2 -Wall -Werror -MMD -MP -DPLATFORM=1 -std=gnu99 -m32 -g -rdynamic -Wl,--no-as-needed -o wac \
-Wl,--start-group wa.a wac.o -Wl,--end-group -lm -ldl -ledit
root@126379a5d272:/wac# ./wac examples_wast/arith.wasm add 2 3
Error(platform_libc.c:48): could not open file 'examples_wast/arith.wasm'
root@126379a5d272:/wac# make examples_wast/arith.wasm
wasm-as examples_wast/arith.wast -o examples_wast/arith.wasm
root@126379a5d272:/wac# ./wac examples_wast/arith.wasm add 2 3
Error(platform_libc.c:50): could not stat file 'examples_wast/arith.wasm' (75)
How did you determine that it is EPROGMISMATCH? If that's really the error, then that seems to indicate to me that docker environment on MacOS isn't translating that syscall correctly (I believe docker on Mac OS leverage virtualbox somehow if I'm remembering correctly). Can you try a small C program that just tries to fstat a file and see if you can reproduce it there. Something like this:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
int main(int argc, char **argv) {
int fd = 0, res = 0;
struct stat sb;
if (!argv[1]) { printf("must specify a file name\n"); exit(1); }
fd = open(argv[1], O_RDONLY);
if (fd < 0) { printf("could not open file '%s'\n", argv[1]); exit(1); }
res = fstat(fd, &sb);
if (res < 0) { printf("could not stat file '%s' (%d)\n", argv[1], errno); exit(1); }
printf("%s file size: %ld\n", argv[1], sb.st_size);
return 0;
}
It's probably worth building it both 32bit and 64bit to see if that is the culprit:
gcc -m32 fstat.c -o fstat32
gcc -m64 fstat.c -o fstat64
./fstat32 LICENSE
./fstat64 LICENSE
Yes, you are right. it looks like a 32bit issue:
root@23f275bd8b8d:/wac# ./fstat32 LICENSE could not stat file 'LICENSE' (75) root@23f275bd8b8d:/wac# ./fstat64 LICENSE LICENSE file size: 17189
I found it was errno 75 which maps to the symbol. e.g. https://unix.superglobalmegacorp.com/Net2/newsrc/sys/errno.h.html
@briangu Interesting. That link classifies 75 under Network File System. Perhaps it's something about the docker file-system mounts. Can you try the following?
./fstat32 /etc/passwd
echo "abc" > /tmp/local-file
./fstat32 /tmp/local-file
BTW, I probably won't be able to help much more with this. It appears to be specific to running 32-bit programs within docker on MacOS (and not specific to wac). I don't have a MacOS system I can easily debug this on. If you are able to come up with a clean fix, I'll be happy to merge it.