简体   繁体   English

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

[英]Problems calling syscall function in C

For a homework assignment, I have to modify the linux kernel. 对于家庭作业,我必须修改linux内核。

I am working on a virtual machine, and I added a system call to the kernel, which I called get_unique_id . 我在虚拟机上工作,并且向内核添加了系统调用,我将其称为get_unique_id Here is the code for get_unique_id.c : 这是get_unique_id.c的代码:

#include <linux/linkage.h>
#include <asm/uaccess.h>

asmlinkage long sys_get_unique_id(int * uuid)
{
    // static because we want its state to persist between calls
    static int uid = 0;

    ++uid;

    // assign new uid value to user-provided mem location
    // returns non-zero if success or -EFAULT otherwise
    int ret = put_user(uid, uuid);
    return ret;
}

I also added this line to syscalls.h : 我还将此行添加到syscalls.h

asmlinkage long sys_get_unique_id(int * uuid);

This line to syscall_32.tbl : 这行到syscall_32.tbl:

383 i386    get_unique_id       sys_get_unique_id

And finally this line to syscall_64.tbl : 最后这行到syscall_64.tbl

548 common  get_unique_id       sys_get_unique_id

After recompiling and reloading the kernel, I wrote a little C program to test my system call, here is the code for the C test file : 重新编译并重新加载内核后,我编写了一些C程序来测试系统调用,这是C测试文件的代码:

// get_unique_id_test.c
#include <stdio.h>
#include <limits.h>

#include "syscalls_test.h"

int main(void)
{
    // initialize the ints we want
    int id1;
    int id2;

    // check the id's are unique and that no error occured
    for (int i = INT_MIN; i < INT_MAX - 1; i += 2) {
        long ret1 = get_unique_id(&id1);
        long ret2 = get_unique_id(&id2);

        if (ret1 != 0)
            printf("ERROR: get_unique_id returned: %ld\n", ret1);

        if (ret2 != 0)
            printf("ERROR: get_unique_id returned: %ld\n", ret2);

        if (id2 != id1 + 1)
            printf("ERROR: successive id's did not increment properly: id1 = %d, id2 = %d\n", id1, id2);
    }

    return 0;
}

And its header file : 及其头文件:

// syscalls_test.h
#include <errno.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

#define __NR_get_unique_id 383

inline long get_unique_id(int * uuid)
{
    return syscall(__NR_get_unique_id, uuid) ? errno : 0;
}

Unfortunately, while trying to compile the C test file with the following command : gcc -std=c99 get_unique_id_test.c -o get_unique_id_test , I get the following error : 不幸的是,在尝试使用以下命令编译C测试文件: gcc -std=c99 get_unique_id_test.c -o get_unique_id_test ,出现以下错误:

In file included from get_unique_id_test.c:4:0:
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function        ‘syscall’ [-Wimplicit-function-declaration]
     return syscall(__NR_get_unique_id, uuid) ? errno : 0;
     ^
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
     return syscall(__NR_get_unique_id, uuid) ? errno : 0;
     ^
/tmp/cc1euZ3r.o: In function `main':
get_unique_id_test.c:(.text+0x22): undefined reference to `get_unique_id'
get_unique_id_test.c:(.text+0x34): undefined reference to `get_unique_id'
collect2: error: ld returned 1 exit status

It appears gcc cannot find the function get_unique_id(int * uuid) , which is declared in syscalls_test.h , and the syscall function, which should be declared, I believe, in syscall.h , right ? 看来GCC找不到功能get_unique_id(int * uuid)这是在宣布syscalls_test.hsyscall函数,应声明,我相信,在syscall.h ,对不对?

I don't understand why this happens. 我不明白为什么会这样。 Does anybody have an idea ? 有人有主意吗?

EDIT : my problems were solved using a3f's solution (see below) PLUS moving the #include "syscalls_test.h" at the very top of the file, as he said in the comments. 编辑:使用A3F的解决方案(见下文)PLUS移动我的问题就解决了#include "syscalls_test.h"在文件的最顶端,因为他在评论中说。 Thank you very much. 非常感谢你。

  • #define _GNU_SOURCE before including unistd.h or any other header as syscall(2) is not POSIX. #define _GNU_SOURCE在包含unistd.h或任何其他标头之前将#define _GNU_SOURCEsyscall(2)不是POSIX。
  • Use static inline instead of plain inline . 使用static inline而不是普通inline Plain inline supplies an inline definition, but the compiler is free to ignore it and use the external definition instead, which you aren't providing. Plain inline提供了一个内联定义,但是编译器可以随意忽略它,而可以使用您未提供的外部定义。

请尝试以下方法:

 #include <unistd.h> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM