实现vroperation系统调用后遇“Function not implemented”错误求助
排查自定义系统调用vroperation的"Function not implemented"错误
问题背景
尝试在内核空间实现vroperation系统调用,并在glibc中编写包装函数支持用户态调用,但运行用户程序时提示“Function not implemented”错误。已完成的代码修改如下:
GLIBC修改
// glibc/srcdir/sysdeps/unix/sysv/linux/sys/syscall.h #ifndef __NR_vroperation #define __NR_vroperation 285 #define __NR_vroperation 338 #endif /* __NR_vroperation */ // glibc/srcdir/sysdeps/unix/syscalls.list vroperation - vroperation i:iii __vroperation vroperation // glibc/srcdir/sysdeps/generic/vroperation.c __vroperation (int vr_index, int oper, int flags) stub_warning (vroperation) weak_alias (__vroperation, vroperation) // 其他头文件与配置修改 glibc/srcdir/conform/data/unistd.h-data:603:function int vroperation(int, int, int); glibc/srcdir/include/unistd.h:198:extern int __vroperation(int __vr_index, int __oper, int __flags); glibc/srcdir/posix/unistd.h:686:extern int vroperation (int __vr_index, int __oper, int __flags) __THROW; glibc/srcdir/posix/Versions:111: vroperation; glibc/srcdir/posix/Makefile:180: vroperation \ glibc/srcdir/posix/annexc.c:544: "ttyname_r", "unlink", "vroperation", "write"
Linux内核修改
// arch/x86/entry/syscalls/syscall_64.tbl 361:338 64 vroperation __x64_sys_vroperation // arch/x86/entry/syscalls/syscall_32.tbl 300:285 i386 vroperation sys_vroperation __ia32_sys_vroperation // kernel/sys.c 2527:SYSCALL_DEFINE3(vroperation, int, vr_index, int, oper, int, flags) // kernel/sys_ni.c 185:COND_SYSCALL(vroperation);
Strace输出
execve("/tmp/vroperation", ["/tmp/vroperation", "delete", "0"], 0x7fffaa0d51e0 /* 23 vars */) = 0 /tmp/strace: [ Process PID=19284 runs in 32 bit mode. ] brk(NULL) = 0x9e63000 brk(0x9e63880) = 0x9e63880 set_thread_area({entry_number=-1, base_addr=0x9e63380, limit=0x0fffff, seg_32bit=1, contents=0, read_exec_only=0, limit_in_pages=1, seg_not_present=0, useable=1}) = 0 (entry_number=12) set_tid_address(0x9e633e8) = 19284 set_robust_list(0x9e633ec, 12) = 0 rseq(0x9e63820, 0x20, ugetrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0 readlinkat(AT_FDCWD, "/proc/self/exe", "/var/tmp/vroperation", 4096) = 20 getrandom("\xbd\x59\x2c\xbd", 4, GRND_NONBLOCK) = 4 brk(NULL) = 0x9e63880 brk(0x9e84880) = 0x9e84880 brk(0x9e85000) = 0x9e85000 mprotect(0x80d9000, 12288, PROT_READ) = 0 dup(2) = 3 fcntl64(3, F_GETFL) = 0x2 (flags O_RDWR) statx(3, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS, stx_attributes=0, stx_mode=S_IFCHR|0622, stx_size=0, ...}) = 0 write(3, "vroperation: Function not implem"..., 38vroperation: Function not implemented ) = 38 close(3) = 0 brk(0x9e84000) = 0x9e84000 exit_group(1) = ? +++ exited with 1 +++
排查与解决步骤
1. 修复glibc存根函数的致命问题
从sysdeps/generic/vroperation.c的代码看,你使用了stub_warning(vroperation)——这是glibc的存根占位函数,会直接返回ENOSYS错误并打印警告,完全不会调用内核系统调用。必须替换为真正的系统调用包装:
#include <sys/syscall.h> #include <errno.h> int __vroperation(int vr_index, int oper, int flags) { return syscall(__NR_vroperation, vr_index, oper, flags); } weak_alias (__vroperation, vroperation)
重新编译并安装glibc,确保用户程序链接到修改后的版本。
2. 确认32位内核系统调用的实现完整性
- 检查
kernel/sys.c中的SYSCALL_DEFINE3(vroperation)是否有完整的函数体,不能只写宏定义而没有实现逻辑。如果函数体为空或未实现,内核会返回ENOSYS。 - 注释掉
kernel/sys_ni.c中的COND_SYSCALL(vroperation):这行是系统调用未实现时的 fallback,会覆盖真正的实现,导致内核返回错误。 - 查看内核编译后的
System.map文件,搜索sys_vroperation或__ia32_sys_vroperation,确认符号存在,说明系统调用已编译进内核。 - 用
uname -r确认当前运行的是修改后的内核版本,而非原系统内核。
3. 校验32位系统调用号一致性
- 确保内核
syscall_32.tbl中32位系统调用号285未被其他系统调用占用,且与glibc中32位环境下的__NR_vroperation值完全一致。 - 检查glibc的
sys/syscall.h:你同时定义了32位和64位的__NR_vroperation,需确保32位glibc编译时使用的是285,可以通过编译后的头文件验证。
4. 确认用户程序依赖的glibc版本
用ldd /tmp/vroperation查看程序依赖的libc路径,确保指向你修改并编译的glibc库,而非系统默认的glibc。如果路径不对,需要调整程序的链接环境(比如用LD_LIBRARY_PATH指定自定义glibc路径)。
内容的提问来源于stack exchange,提问作者prashanthlinganna
相关产品推荐
相关产品推荐

