我正在试验C到WebAssembly。但我不理解以下内容:
int atAddressN(unsigned int idx) {
unsigned int* intptr = 0;
return intptr[idx];
}
int atAddress2(unsigned int idx) {
unsigned int* intptr = 0;
return intptr[2];
}
结果如下wasm/wat:
(module
(table 0 anyfunc)
(memory $0 1)
(export "memory" (memory $0))
(export "atAddressN" (func $atAddressN))
(export "atAddress2" (func $atAddress2))
(func $atAddressN (; 0 ;) (param $0 i32) (result i32)
(unreachable)
(unreachable)
)
(func $atAddress2 (; 1 ;) (param $0 i32) (result i32)
(i32.load offset=8
(i32.const 0)
)
)
)
所以第二个函数很好,但第一个函数只产生(unreachable)
。我应该做其他事情来编译它吗?
空指针取消引用似乎确实是个问题,改为:
int atAddressN(unsigned int* intptr, unsigned int idx) {
return intptr[idx];
}
int atAddress2(unsigned int* intptr, unsigned int idx) {
return intptr[2];
}
中的结果
(module
(table 0 anyfunc)
(memory $0 1)
(export "memory" (memory $0))
(export "atAddressN" (func $atAddressN))
(export "atAddress2" (func $atAddress2))
(func $atAddressN (; 0 ;) (param $0 i32) (param $1 i32) (result i32)
(i32.load
(i32.add
(get_local $0)
(i32.shl
(get_local $1)
(i32.const 2)
)
)
)
)
(func $atAddress2 (; 1 ;) (param $0 i32) (param $1 i32) (result i32)
(i32.load offset=8
(get_local $0)
)
)
)
然后,我将调用以0
作为第一个参数的函数。
创建一个调用函数的测试用例,使用调试符号-g
进行编译,并使用类似gdb
的调试器逐步完成它。这是一个典型的调试会话。
程序接收到信号SIGSEGV,分段故障。0x0000000000401147在e.c:4的atAddressN(idx=3(中4返回intptr[idx];
(gdb) print intptr[idx]
Cannot access memory at address 0xc
gdbprint
命令揭示了这个问题。
在测试方面,WebAssembly并没有什么特别之处。这些测试的子代通常也会编译为可执行文件。
//test.c
int main (){ printf("int 3 is %in", atAddressN(3)); return 0;}