Full process name from task_struct
Did you mean exe file name? You can get the exe of current process as follows :
char *pathname,*p;
mm = current->mm;
if (mm) {
down_read(&mm->mmap_sem);
if (mm->exe_file) {
pathname = kmalloc(PATH_MAX, GFP_ATOMIC);
if (pathname) {
p = d_path(&mm->exe_file->f_path, pathname, PATH_MAX);
/*Now you have the path name of exe in p*/
}
}
up_read(&mm->mmap_sem);
}
How to get process name from PID using C
To find the task_struct of a process we can make use of the function pid_task defined in kernel/pid.c .
struct task_struct *pid_task(struct pid *pid, enum pid_type type)
Arguments:
pid : Pointer to the struct pid of the process.
pid_type: PIDTYPE_PID,
PIDTYPE_PGID,
PIDTYPE_SID,
PIDTYPE_MAX
To find the pid structure if we have the pid of a process we can use the functionfind_get_pid which is also defined in kernel/pid.c
struct pid *find_get_pid(pid_t nr)
In the below module we create a read/write proc entry named task_by_pid. Which ever process we want to find the task_struct of using its pid we can write to number into the proc entry.
When we read the proc entry, it will display the name of the process corresponding to the pid we wrote into it.
proc_task_pid:
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/proc_fs.h>
#include <linux/pid.h>
#include <linux/pid_namespace.h>
int p_id;
struct pid *pid_struct;
struct task_struct *task;
static struct proc_dir_entry *proc_write_entry;
char *proc_name="task_by_pid";
int read_proc(char *buf,char **start,off_t offset,int count,int *eof,void *data )
{
int len=0;
pid_struct = find_get_pid(p_id);
task = pid_task(pid_struct,PIDTYPE_PID);
len = sprintf(buf,"\nname %s\n ",task->comm);
return len;
}
int write_proc(struct file *file,const char *buf,int count,void *data )
{
int ret;
char *id;
id = (char *)kmalloc(1000*sizeof(char),GFP_KERNEL);
printk(KERN_INFO "buf passed %s",buf);
if(copy_from_user(id,buf,count))
return -EFAULT;
printk(KERN_INFO "id passed %s",id);
p_id = simple_strtoul(id,NULL,0);
printk(KERN_INFO "pid %d ret %d",p_id,ret);
return sizeof(buf);
}
void create_new_proc_entry()
{
proc_write_entry = create_proc_entry(proc_name,0666,NULL);
if(!proc_write_entry)
{
printk(KERN_INFO "Error creating proc entry");
return -ENOMEM;
}
proc_write_entry->read_proc = read_proc ;
proc_write_entry->write_proc = write_proc;
printk(KERN_INFO "proc initialized");
}
int proc_init (void) {
create_new_proc_entry();
return 0;
}
void proc_cleanup(void) {
printk(KERN_INFO " Inside cleanup_module\n");
remove_proc_entry(proc_name,NULL);
}
MODULE_LICENSE("GPL");
module_init(proc_init);
module_exit(proc_cleanup);
Use the following make file to compile it:
ifneq ($(KERNELRELEASE),)
obj-m := proc_task_pid.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
Compile it using
$make
Insert it into the kernel:
$ insmod proc_task_pid.ko
Now let us try to find the name of the process with pid "1", which is always init.
$ printf "1" > /proc/task_by_pid
$ cat /proc/task_by_pid
name init
As expected the output is "init". Thus we can find the task_struct of any process using its pid.
Source code from here.
linux get process name from pid within kernel
struct task_struct contains a member called comm, it contains executable name excluding path
.
Get current macro from this file will get you the name of the program that launched the current process (as in insmod / modprobe).
Using above info you can use get the name info.
get _complete_ process name from pid
You could always look at how the kernel does it. You'll see the function:
proc_pid_cmdline(struct task_struct *task, char * buffer)
It's fairly easy to follow but once you have the task_struct
for the process you are interested in you use access_process_vm()
to slurp the bits you want from mm->arg_start
.
printing the comm field of the `current` task_struct, Linux kernel
What you see is exactly the process name, the swapper process runs each instance per CPU on a SMP system, and they are distinguished by appending the process number to it, so on the 1st CPU, the process is swapper/0
, on the 2nd it would be swapper/1
, and so on.
You can find out in the kernel source:
http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.5#L5136
#if defined(CONFIG_SMP)
sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu);
#endif
Here INIT_TASK_COMMON is defined as "swapper" in header file, and cpu is current cpu number.
How does the kernel use task_struct?
Yes, the task_struct
structure contains all the information about a process. You can obtain a pointer to the structure that describes the current process using the current
macro as follows:
struct task_struct *p = current;
If you want to get the structure that describes a process given a pid
, you can use the find_task_by_vpid
function as follows:
read_lock(&tasklist_lock);
p = find_task_by_vpid(pid);
if (p) get_task_struct(p);
read_unlock(&tasklist_lock);
if (p == NULL) {
// Task not found.
}
// Later, once you're finished with the task, execute:
put_task_struct(p);
Finally, if you want to iterate over all processes, you can use for_each_process
as follows:
read_lock(&tasklist_lock);
for_each_process(p) {
// p is a pointer to a task_struct instance.
}
read_unlock(&tasklist_lock);
If you want to an exclusive access to the task list to be able to make changes to one or more fields in the structure, write_lock_irqsave
must be used instead of read_lock
.
Siblings of `struct task_struct current` always include a process with `pid = 0`
Here is an illustration of how two sibling child processes are linked into their parent process's list of children:
PARENT CHILD 1 CHILD 2
====== ======= =======
task_struct task_struct
+-------------+ +-------------+
| | | |
task_struct ~ ~ ~ ~
+-------------+ | | | |
| | |-------------| |-------------|
~ ~ | children | | children |
| | | | | |
. . |-------------| . . |-------------| . . |-------------| . .
| children | | sibling | | sibling |
X==>| prev | next |<===>| prev | next |<===>| prev | next |<==X
. . |-------------| . . |-------------| . . |-------------| . .
| sibling | | | | |
| | ~ ~ ~ ~
|-------------| | | | |
| | +-------------+ +-------------+
~ ~
| | 'X's are joined together, making
+-------------+ a doubly linked, circular list.
Although children
and sibling
are both of type struct list_head
, children
is being used as an actual list head (linking to its list of child processes), whereas sibling
is being used as a list entry.
The parent's children.next
link points to child 1's sibling
member, child 1's sibling.next
link points to child 2's sibling
member, and child 2's sibling.next
link points back to the parent's children
member (the list head). Similarly, the parent's children.prev
link points to child 2's sibling
member, child 2's sibling.prev
link points to child 1's sibling
member, and child 1's sibling.prev
link points back to the parent's children
member.
The list_for_each(pos, head)
macro visits each node pos
in the list, starting at head->next
, while pos != head
.
Normally, the head
parameter of list_for_each(pos, head)
should be an actual list head, but the macro cannot tell the difference between a list head and a list entry. They are both the same type and all the nodes are linked together circularly. (The whole list consists of a list head with zero or more list entries linked in a circle. For an empty list, the list head just links back to itself.) The list_for_each
macro will just iterate around the doubly linked list until it get back to where it started.
If list_for_each(pos, head)
was called with head
pointing to the parent's children
member, then pos
would point to child 1's sibling
member in the first iteration, and would point to child 2's sibling
member in the second iteration, and would terminate the loop with pos
pointing back to the parent's children
member. Inside the loop, list_entry(pos, struct task_struct, sibling)
would correctly point to the beginning of the struct task_struct
for the child process.
Let us say that child 1 is the current
process. OP's code is using list_for_each(pos, head)
with head
pointing to child 1's sibling
member. Therefore, pos
would point to child 2's sibling
member in the first iteration, and would point to the parent's children
member in the second iteration, and would terminate the loop with pos
pointing back to child 1's sibling
member. Inside the loop, list_entry(pos, struct task_struct, sibling)
would correctly point to the beginning of child 2's struct task_struct
in the first iteration, but pos
would point to somewhere before the beginning of the parent's struct task_struct
in the second iteration. That is the where the problem lies in OP's code.
Where does task_struct get initialized in the Linux kernel?
Since the only way to create a new process in Linux is through the clone()
syscall (or other variants like fork()
), there is no real function to "create a new task" from scratch, but there sure is a function to duplicate an existing task, applying the needed modifications. The function used for this is copy_process()
, which uses dup_task_struct()
to duplicate the associated struct task_struct
.
There is however one special exception to this rule: the init process (the first process created after booting) is created by the kernel itself (every other process is then created by init or by some child of init through clone()
+ execve()
). The task_struct
for the init task is statically defined at compile time (see here). You can look at this other answer if you want to know more.
Related Topics
Undefined Reference to Symbol 'Pthread_Key_Delete@@Glibc_2.2.5
Check If All Lines from One File Are Present Somewhere in Another File
Cloudera Manager Failed to Authenticate: Exhausted Available Authentication Methods
Embedding an Application (In This Case a Terminal) Within a Qt Application
Self Updating Bash Script from Github
How to List Dependencies of C/C++ Static Library
Unix Bash Shell Programming If Directory Exists
How to Generate a Static HTML File from a Swagger Documentation
How to Make Sure Only One Instance of a Bash Script Is Running at a Time
Eclipse Doesn't Use The Path Set in .Bashrc
Why Use G++ Instead of Gcc to Compile *.Cc Files
Does I2C Driver Need to Be Implemented Just Like Any Other Character Device Driver