Skip to content

Instantly share code, notes, and snippets.

@bvibber
Created February 9, 2020 21:48
Show Gist options
  • Save bvibber/98ae07f1d327607fbe417312805f7bb1 to your computer and use it in GitHub Desktop.
Save bvibber/98ae07f1d327607fbe417312805f7bb1 to your computer and use it in GitHub Desktop.
Test case for emscripten stray syscall issue

The library code in lib.c conditionally calls the POSIX read syscall causing an import, but optimization on the final output eliminates that code path.

Result is a stray __syscall3 function which references FS, imported by the wasm but unused in it. Since the FS isn't defined because of using -s NO_FILESYSTEM=1, Closure sees it's undefined and either turns it into a (void 0) (1.39.6) or fails immediately (1.39.7).

#include "lib.h"
size_t read_something(state_t *state) {
const size_t n_bytes = 512;
char buffer[n_bytes];
if (state->fd) {
return read(state->fd, buffer, n_bytes);
} else {
return state->read(buffer, n_bytes, state->user_data);
}
}
#include <unistd.h>
typedef size_t (*read_func)(char *buffer, size_t n_bytes, void *user_data);
typedef struct {
int fd;
read_func read;
void *user_data;
} state_t;
extern size_t read_something(state_t *state);
OPTS=-O3 -g1 --closure 1 -s NO_FILESYSTEM=1
test.js : lib.o test.o
emcc $(OPTS) -o test.js lib.o test.o
lib.o : lib.c lib.h
emcc $(OPTS) -c -o lib.o lib.c
test.o : test.c lib.h
emcc $(OPTS) -c -o test.o test.c
clean :
rm -f test.js
rm -f test.wasm
rm -f test.o
rm -f lib.o
#include <stdio.h>
#include "lib.h"
static size_t fake_read(char *buffer, size_t n_bytes, void *user_data) {
(void)user_data;
for (size_t i = 0; i < n_bytes; i++) {
buffer[i] = 'A';
}
return n_bytes;
}
int main(int argc, const char **argv) {
state_t state;
state.fd = 0;
state.read = fake_read;
state.user_data = NULL;
size_t bytes_read = read_something(&state);
printf("read %zu bytes of fake stuff\n", bytes_read);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment