在 C 中调用系统调用函数时出现问题

Scr*_*own 3 c linux gcc system-calls linux-kernel

为了完成家庭作业,我必须修改 Linux 内核。

\n\n

我正在虚拟机上工作,我向内核添加了一个系统调用,我将其称为get_unique_id. 这是代码get_unique_id.c

\n\n
#include <linux/linkage.h>\n#include <asm/uaccess.h>\n\nasmlinkage long sys_get_unique_id(int * uuid)\n{\n    // static because we want its state to persist between calls\n    static int uid = 0;\n\n    ++uid;\n\n    // assign new uid value to user-provided mem location\n    // returns non-zero if success or -EFAULT otherwise\n    int ret = put_user(uid, uuid);\n    return ret;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我还将这一行添加到syscalls.h

\n\n
asmlinkage long sys_get_unique_id(int * uuid);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这一行到 syscall_32.tbl :

\n\n
383 i386    get_unique_id       sys_get_unique_id\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后这一行syscall_64.tbl

\n\n
548 common  get_unique_id       sys_get_unique_id\n
Run Code Online (Sandbox Code Playgroud)\n\n

重新编译并重新加载内核后,我编写了一个小 C 程序来测试我的系统调用,以下是 C 测试文件的代码:

\n\n
// get_unique_id_test.c\n#include <stdio.h>\n#include <limits.h>\n\n#include "syscalls_test.h"\n\nint main(void)\n{\n    // initialize the ints we want\n    int id1;\n    int id2;\n\n    // check the id\'s are unique and that no error occured\n    for (int i = INT_MIN; i < INT_MAX - 1; i += 2) {\n        long ret1 = get_unique_id(&id1);\n        long ret2 = get_unique_id(&id2);\n\n        if (ret1 != 0)\n            printf("ERROR: get_unique_id returned: %ld\\n", ret1);\n\n        if (ret2 != 0)\n            printf("ERROR: get_unique_id returned: %ld\\n", ret2);\n\n        if (id2 != id1 + 1)\n            printf("ERROR: successive id\'s did not increment properly: id1 = %d, id2 = %d\\n", id1, id2);\n    }\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

及其头文件:

\n\n
// syscalls_test.h\n#include <errno.h>\n#include <sys/syscall.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#define __NR_get_unique_id 383\n\ninline long get_unique_id(int * uuid)\n{\n    return syscall(__NR_get_unique_id, uuid) ? errno : 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

不幸的是,在尝试使用以下命令编译 C 测试文件时:gcc -std=c99 get_unique_id_test.c -o get_unique_id_test,我收到以下错误:

\n\n
In file included from get_unique_id_test.c:4:0:\nsyscalls_test.h: In function \xe2\x80\x98get_unique_id\xe2\x80\x99:\nsyscalls_test.h:10:5: warning: implicit declaration of function        \xe2\x80\x98syscall\xe2\x80\x99 [-Wimplicit-function-declaration]\n     return syscall(__NR_get_unique_id, uuid) ? errno : 0;\n     ^\nsyscalls_test.h: In function \xe2\x80\x98get_unique_id\xe2\x80\x99:\nsyscalls_test.h:10:5: warning: implicit declaration of function \xe2\x80\x98syscall\xe2\x80\x99 [-Wimplicit-function-declaration]\n     return syscall(__NR_get_unique_id, uuid) ? errno : 0;\n     ^\n/tmp/cc1euZ3r.o: In function `main\':\nget_unique_id_test.c:(.text+0x22): undefined reference to `get_unique_id\'\nget_unique_id_test.c:(.text+0x34): undefined reference to `get_unique_id\'\ncollect2: error: ld returned 1 exit status\n
Run Code Online (Sandbox Code Playgroud)\n\n

看起来 gcc 找不到get_unique_id(int * uuid)在 中声明的函数syscalls_test.h,以及syscall我相信应该在 中声明的函数,syscall.h对吗?

\n\n

我不明白为什么会发生这种情况。有人有想法吗?

\n\n

编辑:我的问题是使用 a3f 的解决方案解决的(见下文),并且将 移动#include "syscalls_test.h"到文件的最顶部,正如他在评论中所说。非常感谢。

\n

a3f*_*a3f 5

  • #define _GNU_SOURCE在包含unistd.h或任何其他syscall(2)非 POSIX 标头之前。
  • 使用static inline而不是普通的inline. Plaininline提供了内联定义,但编译器可以自由地忽略它并使用您未提供的外部定义。