【发布时间】:2020-05-19 19:50:21
【问题描述】:
我正在基于tutorial 编写一个简单的系统调用,并启动到带有我的系统调用的新内核,但是当我编译一个测试并执行它时,它会导致分段错误(核心转储)。 我的 my_syscall.h(本教程中的 hello.c 等效项)看起来像这样。
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/current.h>
struct smallStruct {
int integer;
char str[20];
};
struct bigStruct {
long id;
struct smallStruct a;
struct smallStruct b;
struct smallStruct c;
};
asmlinkage long test_syscall(int pid, struct bigStruct *info)
{
info->id = pid;
info->a.integer = 0;
info->a.str[0] = 'A';
info->a.str[1] = '\0';
info->b.integer = 1;
info->b.str[0] = 'B';
info->b.str[1] = '\0';
info->c.integer = 2;
info->c.str[0] = 'C';
info->c.str[1] = '\0';
return 0;
}
我实际上尝试编写一个系统调用来获取一些信息并存储回*info,我需要smallStruct中的str,但是每次我尝试修改str时,都会导致分段错误(核心转储),当我删除对str 的这些修改以暂时避免核心转储时,它仍然无法按预期工作。这是我的测试文件的样子:
#include <sys/syscall.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
struct smallStruct
{
int integer;
char str[20];
};
struct bigStruct
{
long id;
struct smallStruct a;
struct smallStruct b;
struct smallStruct c;
};
int main()
{
long sys_return_value;
struct bigStruct info;
sys_return_value = syscall(548, 1, &info);
printf("id = %ld, return %ld\n", info.id, sys_return_value);
return 0;
}
似乎我的测试中的info 根本没有被系统调用修改。
我什至在 my_syscall.h 中使用了printk,而我传递给我的系统调用的pid 根本不正确。这就是printk 在dmesg 中打印的内容
my_syscall 中的id 应该是pid,它在我的测试中通过,值为1。(syscall(548, 1, &info);)
我知道它很长,但如果有人能解释我的工具出了什么问题,我将不胜感激, 谢谢。
【问题讨论】:
-
请勿将文字作为图片发布。
-
看看现有的系统调用如何处理用户指针。
-
表示进程id(我猜是pid?)你可以使用
p_id数据类型。它转换为整数,而不是long -
查看
copy_to_user。 -
您在测试中究竟在打印什么?请发布您用于测试的相同代码。
标签: c linux system-calls