You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:16:00