将word2vec移植到RISC-V:疑似代理内核问题?
我之前在移植应用到RISC-V Spike模拟器时碰到过类似的系统调用报错问题,结合你的场景,给你几个针对性的排查方向:
先定位syscall #179对应的具体操作
首先查RISC-V官方的系统调用编号定义,或者直接查看代理内核(pk)源码里的syscall.h文件,确认179这个编号对应的是哪个系统调用。很可能是word2vec调用了pk尚未实现的syscall——毕竟pk是轻量级内核,不像完整Linux内核支持所有syscall。追踪崩溃前的代码路径
既然程序运行1-2分钟、执行特定循环后才崩溃,你可以在word2vec的关键位置(比如文件IO、内存映射、线程操作这些容易触发syscall的地方)添加简单的printf日志,或者在pk的syscall入口处加日志,记录每次调用的syscall编号和参数,这样就能精准定位到触发错误的那个syscall调用场景。检查pk对该syscall的实现逻辑
找到pk源码中处理该syscall的函数,如果发现函数是空实现(直接返回错误),或者参数处理、返回值逻辑有问题,那基本就能确定是pk的问题了。比如有些和异步IO、高级文件属性相关的syscall,pk通常不会完整实现。对比基准程序与word2vec的syscall差异
你的交叉编译器能正常跑标准基准测试,那可以对比两者的syscall调用情况:要么用模拟环境支持的strace工具跟踪,要么在pk里添加syscall计数代码,统计基准程序和word2vec调用的syscall类型、次数。如果word2vec用到了基准程序没调用过的syscall,那这个syscall大概率就是问题根源。用其他RISC-V模拟器交叉验证
把编译好的word2vec二进制放到QEMU RISC-V模式下运行,如果QEMU能正常跑完,那几乎可以肯定是Spike/pk的兼容性问题;如果QEMU也崩溃,再回头检查word2vec的移植代码(不过你说两个版本都出现同样问题,pk的可能性还是更大)。
我之前遇到过pk不支持某些扩展syscall的情况,比如和文件系统高级操作相关的调用,当时要么修改pk补充了对应的syscall实现,要么在应用里把该调用替换成pk支持的等效操作,问题就解决了。
内容的提问来源于stack exchange,提问作者seanhalle

