简体   繁体   中英

Getting 'ímplicit declaration of function' error while adding a system call in linux

I am trying to add a new system call that displays some information about currently running processes in the system. I created a new struct named proc_info_struct that contains parts of the process information I want to display. Here is the proc_info_struct code defined in procinfo.h header file

#include <linux/types.h>
struct proc_info_struct
{
    pid_t pid;
    pid_t parn_pid;
    pid_t gid;
    unsigned long user_time;
    unsigned long sys_time;
    long state;
    unsigned long long sched_avg_running;
    unsigned int time_slice;
    unsigned int policy;
    unsigned long num_cxs;

    int num_children;
    char* prog;
};

In the system call method(shown below), I try to check if the process specified exists or not by using the kill() function defined in signal.h using this link as a reference. Here is the code which I use to get the process information:

#include <linux/procinfo.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/linkage.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <asm-generic/current.h>
#include <linux/signal.h>

void fill_proc_info(struct proc_info_struct *proc_info, struct task_struct *task)
{
    int num_ch = 0;
    struct list_head* list;
    proc_info->pid = task->pid;
    proc_info->parn_pid = (task->parent)->pid;
    proc_info->gid = task->tgid;
    proc_info->user_time = task->utime;
    proc_info->sys_time = task->stime;
    proc_info->state = task->state;
    proc_info->sched_avg_running = task->cputime_expires.sum_exec_runtime; //average scheduled running time;
    proc_info->policy = task->policy;
    proc_info->time_slice = task->rt.time_slice;
    proc_info->num_cxs = (task->nvcsw) + (task->nivcsw); //number of context switches(both voluntary and involuntary)

    list_for_each(list, &task->children){
        num_ch++;
    }
    proc_info->num_children = num_ch;
    proc_info->prog = task->comm;
}



asmlinkage long sys_getprocinfo(pid_t pid, struct proc_info_struct *proc)
{
    struct task_struct *task;
    struct proc_info_struct *proc_info;

    if(pid)
    {
        //current process
        task = get_current();
        fill_proc_info(proc_info, task);

    }

    else{
        int exists = 0;//checks whether a process exists or not
        for_each_process(task){
        if(task->pid = pid){
            exists = 1;
        }
    }
    if(exists){
        //task = find_task_by_vpid(pid);  we don't need this line now since the task has now been set in for_each_process

         fill_proc_info(proc_info, task);
    }

    else{
        printk("Process doesn't exist");
        return -ESRCH:
    }

    }
    if (copy_to_user(proc, proc_info, sizeof(proc_info)))
        return -EFAULT;
    return 1;

}

When I try to build the kernel by using make I get the following error

错误

As it can be seen above, I have included the signal.h header in the line:

#include <linux/signal.h>

What am I missing here? How is there an alternative way I can check if a given process exists in the system by using its pid other than kill function?

Edit: Using the suggestions in the answer, I replaced the kill function call with for_each_process macro. Now it compiles successfully. I wrote a test code to test the system call. When I give a non-existing pid, the system call works correctly by displaying 'Process doesn't exist' in the kernel log. However, when I give an existing code, it raises the displays error in the kernel log:

BUG: unable to handle kernel NULL pointer dereference at (null)

The test code

int main()
    {
        struct proc_info_struct *proc_info;
        pid_t pid = 0; //I tried 
        /;

        syscall(314, pid, &proc_info);

        printf("Pid: %ld\nParent: %ld\nGid:%ld\nUtime: %lu\nSysTime: 
            %d\nState: %lu\n,Time_Slice: %d\nPolicy: %d\nNum_CXS: %lu\nNumChild: 
            %d\nProg: %s\n",proc_info->pid, proc_info->parn_pid, proc_info->gid, 
            proc_info->user_time, proc_info->sys_time, proc_info->state, proc_info->time_slice, 
            proc_info->policy, proc_info->num_cxs, proc_info->num_children, proc_info->prog);

        return 0;
    }

Kernel code doesn't define user space functions like kill .

For search through processes you can try for_each_process macro, defined in <linux/sched.h> .

UPDATE : BTW, according to comments in your code, you used find_task_by_vpid for some purpose. This function just return task, which has given pid. Why do you not want to use it? Also, you can investigate implementation of the system call kill : how it searches needed task. This system call is defined in kernel/signal.c as SYSCALL_DEFINE2(kill,... .

Also note, that searching task(in any form) and reading its fields should be performed within rcu_read_lock / rcu_read_unlock critical section. This protects tasks lists from element destruction during search.

Tsyvarev right. Linux kernel doesn't contain kill. But it contains sys_kill .

Also, you can look on my test project . There you can find the affl_kill_process() function which kills process.

Try adding

#define _POSIX_SOURCE

before all inclusions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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