我已经通过emscripten使用WASM了几周,并且一直取得良好的进展,直到出现此错误:
exception thrown: RuntimeError: function signature mismatch,RuntimeError: function signature mismatch
这开始是在以前有效的代码中发生的,似乎与WASM有关,原因是WASM缺少对javascript中64位整数的支持以及文件管理中使用的偏移量。我提出了一个孤立的案例:
#include <iostream>
int main(int argc, char const *argv[])
{
char test[30];
std::cout << __LINE__ << std::endl;
FILE *f = fopen("minimal_call_dispatch.cpp","ra");
std::cout << __LINE__ << std::endl;
fseek(f, 100, SEEK_SET);
std::cout << __LINE__ << std::endl;
fclose(f);
std::cout << __LINE__ << std::endl;
return 0;
}
建筑:
call emcc -o ./test.js test_file.cpp -s WASM=1 -s NO_EXIT_RUNTIME=1 -std=c++1z
由于提到的错误,在“ fseek”失败之前输出了“ 6 \ n8 \ n”。
一直沿线的某个地方,我怀疑wasm正在尝试使用与具有64位整数而不是32位整数的javascript通信的标头,但我看不到这是怎么回事。我将尝试重新安装emscripten,但即使该方法可行,我也想更好地了解是什么原因造成的。
作为解决方法,有人知道如何使emcc忽略对64位整数的担心,并将其静默转换为32位吗?毕竟,我不希望解决超过3gig的ram。
i64
,并且可以很好地计算64位整数。只是没有64位地址。 )这意味着编译器已经知道目标计算机是32位,并且size_t
将是32位。"ra"
标志而导致文件不存在时,将fopen()
与r
一起使用将导致分段错误!g++ test_file.cpp -o test.out
如果不存在./test.out
,则运行test_file.cpp
将显示以下内容:
6 8 [2] 14464 segmentation fault (core dumped) ./test.out
所以您的代码是错误的,但是Emscripten为什么会以不同的方式抛出错误?当您使用emcc
而没有像-g
这样的调试标志时,它将具有最小化的环境,不会捕获错误文件段错误,因为这种智能运行时会增加在Web环境中重要的二进制文件大小。结果,运行时将继续运行而忽略segfualt,您将得到一个随机错误。因此function signature mismatch
毫无意义。您可以使用与调试相关的选项来构建它:
emcc -o ./test.html test_file.cpp -s WASM=1 -std=c++1z \ -g4 -s ASSERTIONS=2 -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=1 \ --source-map-base http://your_server_ip:port/
然后打开test.html
,您现在将看到正确的错误:
exception thrown: RuntimeError: abort(segmentation fault) at Error
现在您将不会收到诸如签名不匹配之类的误导性错误:)顺便说一下,用
fopen("minimal_call_dispatch.cpp","ra");
替换fopen("minimal_call_dispatch.cpp","a");
将纠正错误。使用正确的
--source-map-base
服务器IP设置,可以更好地在浏览器中实际获取源test_file.cpp
,以便可以将断点设置为.cpp文件。玩得开心调试:)