【问题标题】:My syscall cause segmentation fault (core dumped)我的系统调用导致分段错误(核心转储)
【发布时间】: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 根本不正确。这就是printkdmesg 中打印的内容

my_syscall 中的id 应该是pid,它在我的测试中通过,值为1。(syscall(548, 1, &amp;info);)

我知道它很长,但如果有人能解释我的工具出了什么问题,我将不胜感激, 谢谢。

【问题讨论】:

  • 请勿将文字作为图片发布。
  • 看看现有的系统调用如何处理用户指针。
  • 表示进程id(我猜是pid?)你可以使用p_id数据类型。它转换为整数,而不是 long
  • 查看copy_to_user
  • 您在测试中究竟在打印什么?请发布您用于测试的相同代码。

标签: c linux system-calls


【解决方案1】:

您将作为进程堆栈部分的一部分的用户指针传递给内核。这是不好的做法,并且永远不会起作用,因为内核内存和用户内存是独立的实体。您需要使用 System API 将指针与用户之间的指针传递给内核内存。查看 copy_to_user 和 copy_from_user 函数。您还可以使用 ioctl 方法在用户/应用程序和内核之间创建一个后门

【讨论】:

  • 非常感谢,我会试试的,非常感谢您的帮助,希望您有愉快的一天^^
  • 你能解释一下为什么“syscall(548, 1, &info);”我得到的pid 应该是1,但是当我在dmesgprintk 时,它具有如图所示的随机值,好吗?我看到很多人这样做,他们成功地传递了价值。
猜你喜欢
  • 1970-01-01
  • 2022-08-23
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 1970-01-01
相关资源
最近更新 更多