当前,当发生Webassembly运行时错误时,堆栈跟踪如下所示(我正在尝试将Csound作为Webassembly运行)
"RuntimeError: integer result unrepresentable
at (<WASM>[5336]+20)
at (<WASM>[1557]+246)
at (<WASM>[408]+1475)
at (<WASM>[6101]+14)
at Object.Module.dynCall_ii (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/libcsound.js:9614:89)
at invoke_ii (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/libcsound.js:8882:32)
at (<WASM>[424]+732)
at (<WASM>[278]+45)
at Module._CsoundObj_performKsmps (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/libcsound.js:9606:128)
at ScriptProcessorNode.audioProcessNode.onaudioprocess (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/CsoundObj.js:272:19)"
(
经过一些研究,我发现格式是
(<WASM>[function_index]+offset)
要查找函数索引的相应名称,您可以使用 binaryen 的wasm-as
-s
选项来生成函数索引
wasm-as libcsound.wast -s libcsound.sym -o libcsound.wasm
这是libcsound.sym的内容
0:Math_pow
1:enlargeMemory
2:getTotalMemory
3:abortOnCannotGrowMemory
...
使用 libcsound.sym,我们可以用 WASM 函数名称来增强示例
RuntimeError: integer result unrepresentable
at (<WASM>[5336]+20) _lrintf
at (<WASM>[1557]+246) _osckk
at (<WASM>[408]+1475) _kperf_nodebug
at (<WASM>[6101]+14) dynCall_ii
at Object.Module.dynCall_ii (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/libcsound.js:9614:89)
at invoke_ii (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/libcsound.js:8882:32)
at (<WASM>[424]+732) _csoundPerformKsmps
at (<WASM>[278]+45) jsCall_vi
at Module._CsoundObj_performKsmps (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/libcsound.js:9606:128)
at ScriptProcessorNode.audioProcessNode.onaudioprocess (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/CsoundObj.js:272:19)
有趣的部分是对 lrintf 的最后一个 C 函数调用。当要转换的浮点数位于长整数范围之外时,此函数可能会导致"整数结果无法表示"陷阱。我编辑了 C 代码以先检查边界,然后再调用 lrint 来解决问题。
更新
使用-g4
并使用 Google Chrome 版本 60.0.3103.0(官方内部版本)时,金丝雀(64 位)函数名称显示在堆栈跟踪中:
Uncaught RuntimeError: integer result unrepresentable
at _lrintf (<WASM>[4176]+6)
at _osckk (<WASM>[1291]+138)
at _kperf_nodebug (<WASM>[257]+768)
at dynCall_ii (<WASM>[4351]+13)
at Object.Module.dynCall_ii (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/libcsound.js:9153:89)
at invoke_ii (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/libcsound.js:8714:32)
at _csoundPerformKsmps (<WASM>[271]+558)
at _CsoundObj_performKsmps (<WASM>[131]+33)
at Module._CsoundObj_performKsmps (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/libcsound.js:9145:128)
at ScriptProcessorNode.audioProcessNode.onaudioprocess (http://192.168.2.39/~manson/emscripten/csound/emscripten/examples/javascripts/CsoundObj.js:269:19)
第一个数字是 WebAssemblyCode
部分中的函数索引。第二个是该函数中的偏移量,以字节为单位,其中生成陷阱(WebAssembly 中的某些指令生成陷阱,这些陷阱转换为 JavaScript 异常)。要映射回函数编号,您可以使用 wabt 提供的工具(预构建版本可从 wasm-stat.us 获得,请参阅生成 URL 等 URL 的"存档二进制文件"步骤https://storage.googleapis.com/wasm-llvm/builds/mac/5128/wasm-binaries-5128.tbz2
)。
您还可以在调试模式下使用 emscripten 来生成Name
节。然后,每个函数索引将映射到一个名称,该名称将显示在回溯中。
您将使用如下命令行:
em++ ./awesome.cc -O2 -g4 -s WASM=1 -o awesome.js -s EXPORTED_FUNCTIONS="['amazing']"
-g4
是添加name
部分的部分。不要随之发布代码!
在 Mac 上,如果您更新到较新的 Safari 技术预览版,您将获得诸如"wasm function: 4@[wasm code]
之类的条目,或者如果您启用了调试,例如wasm function: _spam@[wasm code]
其中spam
是 C 函数的名称。此更改是最近的,需要 STP 30 或更新。其他浏览器也做类似的事情。在所有情况下,它们还需要一个相当新的工具链,因为name
部分的格式已更改。
您得到的错误是因为float
int
转换具有无法准确表示的浮点值。这在 WebAssembly 中捕获,而不是在大多数其他 C++ 实现中生成未指定的值。
最近,在WebAssembly和(我认为?)binaryen的LLVM实现中出现了一些错误,其中一些通常可以推测的操作被提升了检查。该错误很可能存在于您正在运行的代码中,但工具链无条件化该转换的可能性很小,从而导致代码陷阱。更新工具链可能会删除该错误。
解决"整数结果无法表示"问题的一种方法是使用此选项:
-s "BINARYEN_TRAP_MODE='clamp'"
或可能
-s "BINARYEN_TRAP_MODE='js'"
见 https://github.com/kripken/emscripten/wiki/WebAssembly#trap-mode