emscripten-core / emscripten-core/emscripten

ASYNCIFY_PROPAGATE_ADD does not work with -O1 and above

Open
#23,015 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

```
$ emcc --version
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.72 (437140d149d9c977ffc8b09dbaf9b0f5a02db190)
```

`asyncify_test.c`:
```C
#include
#include

void (*indirect_sleep)(unsigned int) = &emscripten_sleep;

EMSCRIPTEN_KEEPALIVE
void my_sleep() {
puts("sleeping");
indirect_sleep(100);
puts("awake");
}

int main() {
my_sleep();
my_sleep();
return 0;
}
```

```
$ emcc -o asyncify_test.js asyncify_test.c \
-O1 \
-sASYNCIFY=1 \
-sASYNCIFY_IGNORE_INDIRECT=1 \
-sASYNCIFY_PROPAGATE_ADD=1 \
-sASYNCIFY_ADD=my_sleep \
-sASYNCIFY_ADVISE=1

[asyncify] emscripten_sleep is an import that can change the state
[asyncify] my_sleep is in the add-list, add
```
Note that `main()` is not instrumented even though `ASYNCIFY_PROPAGATE_ADD` is enabled.

The generated `asyncify_test.js` causes an error when executed:
```
$ node asyncify_test.js
sleeping
awake
sleeping
Aborted(invalid state: 1)
/Users/k/asyncify-test/asyncify_test.js:418
var e = new WebAssembly.RuntimeError(what);
^

RuntimeError: Aborted(invalid state: 1). Build with -sASSERTIONS for more info.
at abort (/Users/k/asyncify-test/asyncify_test.js:418:11)
at Object.handleSleep (/Users/k/asyncify-test/asyncify_test.js:1106:11)
at _emscripten_sleep (/Users/k/asyncify-test/asyncify_test.js:751:23)
at wasm://wasm/adf2820a:wasm-function[6]:0x38d
at wasm://wasm/adf2820a:wasm-function[7]:0x39b
at ret. (/Users/k/asyncify-test/asyncify_test.js:924:24)
at Module._main (/Users/k/asyncify-test/asyncify_test.js:1130:90)
at callMain (/Users/k/asyncify-test/asyncify_test.js:1169:15)
at doRun (/Users/k/asyncify-test/asyncify_test.js:1208:23)
at run (/Users/k/asyncify-test/asyncify_test.js:1221:5)

Node.js v20.11.1
```

It works as expected when built with `-O0`:

```
$ emcc -o asyncify_test.js asyncify_test.c \
-O0 \
-sASYNCIFY=1 \
-sASYNCIFY_IGNORE_INDIRECT=1 \
-sASYNCIFY_PROPAGATE_ADD=1 \
-sASYNCIFY_ADD=my_sleep \
-sASYNCIFY_ADVISE=1

[asyncify] emscripten_sleep is an import that can change the state
[asyncify] my_sleep is in the add-list, add
[asyncify] __original_main can change the state due to my_sleep
[asyncify] main can change the state due to __original_main

$ node asyncify_test.js
sleeping
awake
sleeping
awake
```

Removing `-sASYNCIFY_IGNORE_INDIRECT=1` also fixes the issue.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.