I am fairly new to Linux Kernel modules. I am trying to write a module which allows me to get some information of the init_task process (the initial task with pid = 0). I've written the following code in my module to try and get this information using sched.h
#include <linux/sched.h>
void init_task_info(void) {
struct task_struct *task;
pid_t pid = 0;
task = pid_task(find_vpid(pid), PIDTYPE_PID);
printk(KERN_INFO "init_task state: %s\n", task->state);
}
No matter what I try I get a segmentation fault and am unable to access the init_task process. I have also tried find_task_by_vpid. Any help on what I am doing wrong would be very appreciated.
Related
Recently I've been learning about pthread. Then I suddenly came out of an idea that how does gdb know I create a new thread. Then I wrote down a test code below and started up gdb. I step into pthread_create() function, but instead of letting it return normally, I use return 0 to return pthread_create() function. But gdb still shows that I have only one thread. At first, I thought that gdb got thread information from the return value from the pthread_create() function then I thought gdb might also use child process info to the get thread info so I edited my test code. But the result wasn't what I thought of.
So how does gdb get thread info? What kind of information it needs to know how many threads the main thread have and which thread I'm on.
Code
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include "pthread.h"
void *foo(void *bar) {
while(1) {
printf("hello from thread: %d\n", pthread_self());
sleep(2);
}
}
int main() {
printf("Before fake pthread_create");
pid_t pid;
if ((pid = fork()) == -1) {
perror("fork error");
exit(errno);
}
if (pid == 0) {
while(1) {
sleep(3);
}
}
if (pid > 0) {
pthread_t thread;
pthread_create(&thread, NULL, foo, NULL);
while(1) {
printf("hello from thread: %d\n", pthread_self());
sleep(2);
}
return 0;
}
}
How does gdb detect pthread?
GDB sets internal breakpoint on _dl_debug_state, which allows it track which shared libraries are loaded (this is necessary for debugging shared libraries).
When it observes that libpthread.so is loaded, it loads libthread_db.so.1 into its own process space (into GDB itself, not into the program being debugged), and asks that library to notify GDB when new threads are created and when they are destroyed. Documentation.
The libthread_db has intimate knowledge of the internals of libpthread, and installs appropriate hooks to achieve such notification.
There are 2 main mechanisms that debuggers use on linux, and neither of them are very pretty. There is so much detail here that I can only point you there and hope.
One is ptrace which allows the debugger to follow along as the program does things, such as executing system commands like pthread_create, or specific events happen, such as new threads starting, and control the monitored program: http://man7.org/linux/man-pages/man2/ptrace.2.html
The other is the /proc/ file system which reveals lots of information about a process: http://man7.org/linux/man-pages/man5/proc.5.html
In particular ls -l /proc/self/tasks shows you what threads ls has (only 1).
I got a kernel panic, and can't figure out why.
What conditions could possibly cause the following function to crash in a kernel extension in OS X 10.11.3, resulting in a panic?
static int parent_pid(int pid) {
int ppid = 0;
proc_t process = proc_find(pid);
if (process) {
ppid = proc_ppid(process);
proc_rele(process);
}
return ppid;
}
The panic occurred inside the proc_rele(), as it called _lck_mtx_lock in turn. To the best of my knowledge, the proc_rele() is used absolutely correctly here. There are no other calls to proc_find() or proc_self() in the entire kext, so the reason shouldn't be a missing proc_rele() somewhere else in the code.
Are there some kind of race conditions or thread issues I haven't considered? Do I need to protect calls to proc_find()/proc_rele() with a lock, for example?
I'm working on an OS class project with a variant of HOCA system.
I'm trying to create the interrupt handler part of the OS where I/O device interrupts are detected and handled.
(If you have no idea about HOCA, that's fine) My question is really about the internal manipulation of C.
The whole system work like this:
Main function of the OS calls an init() where all the parts are initialized.
After initializing the OS, the root process is created and the first application is schedule()'ed to the specific application. Then the application processes are created and schedule()'ed in a tree structure which rooted from the root process.
void schedule(){
proc_t *front;
front = headQueue(RQ); //return the first available process in the Ready Queue
if (checkPointer(front)) {
intschedule(); // load a timeslice to the OS
LDST(&(front->p_s)); // load the state to the OS
// so that OS can process the application specified by p_s
// LDST() is system function to load a state to processor
}
else {
intdeadlock(); // unlock a process from the blocked list and put in RQ
}
}
Using gdb, I see everything is ok, until it processes right before if(checkPointer(front))
int checkPointer(void *p){
return ((p != (void *) ENULL)&&(p != (void *)NULL));
}
gdb respond:
trap: nonexistant memory address: -1 memory size: 131072 ERROR:
address greater than MEMORYSIZE
what's going wrong with this?
checkPointer() is located in another file.
Your help is much appreciated.
Do I need to include a library?
Can anyone please elaborate in it?
I know is used to get the process id of the current task where is being called from
But I want to printk something with current->pid
printk("My current process id/pid is %d\n", current->pid);
...and is giving me an error
error: dereferencing pointer to incomplete type
You're looking for #include <linux/sched.h>. That's where task_struct is declared.
Your code should work. You are probably missing some header.
current is a per-cpu variable defined in linux/arch/x86/include/asm/current.h (all the code is for the case of x86):
DECLARE_PER_CPU(struct task_struct *, current_task);
static __always_inline struct task_struct *get_current(void)
{
return percpu_read_stable(current_task);
}
#define current get_current()
current points to the task running on a CPU at a given moment. Its type is struct task_struct and it is defined in linux/include/linux/sched.h:
struct task_struct {
...
pid_t pid; // process identifier
pid_t tgid; // process thread group id
...
};
You can browse the code for these files in the Linux Cross Reference:
current.h
sched.h
I think you're looking for the getpid() system call. I don't know what current is though.
Is there an efficient way of finding the task_struct for a specified PID, without iterating through the task_struct list?
What's wrong with using one of the following?
extern struct task_struct *find_task_by_vpid(pid_t nr);
extern struct task_struct *find_task_by_pid_ns(pid_t nr,
struct pid_namespace *ns);
If you want to find the task_struct from a module, find_task_by_vpid(pid_t nr) etc. are not going to work since these functions are not exported.
In a module, you can use the following function instead:
pid_task(find_vpid(pid), PIDTYPE_PID);
There is a better way to get the instance of task_struct from a module.
Always try to use wrapper function/ helper routines because they are designed in such a way if driver programmer missed something, the kernel can take care by own. For eg - error handling, conditions checks etc.
/* Use below API and you will get a pointer of (struct task_struct *) */
taskp = get_pid_task(pid, PIDTYPE_PID);
and to get the PID of type pid_t. you need to use below API -
find_get_pid(pid_no);
You don't need to use "rcu_read_lock()" and "rcu_read_unlock()" while calling these API's because "get_pid_task()" internally calls rcu_read_lock(),rcu_read_unlock() before calling "pid_task()" and handles concurrency properly. That's why I have said above use these kind of wrapper always.
Snippet of get_pid_task() and find_get_pid() function below :-
struct task_struct *get_pid_task(struct pid *pid, enum pid_type type)
{
struct task_struct *result;
rcu_read_lock();
result = pid_task(pid, type);
if (result)
get_task_struct(result);
rcu_read_unlock();
return result;
}
EXPORT_SYMBOL_GPL(get_pid_task);
struct pid *find_get_pid(pid_t nr)
{
struct pid *pid;
rcu_read_lock();
pid = get_pid(find_vpid(nr));
rcu_read_unlock();
return pid;
}
EXPORT_SYMBOL_GPL(find_get_pid);
In a kernel module, you can use wrapper function in the following way as well -
taskp = get_pid_task(find_get_pid(PID),PIDTYPE_PID);
PS: for more information on API's you can look at kernel/pid.c
No one mentioned that the pid_task() function and the pointer (which you obtain from it) should be used inside RCU critical section (because it uses RCU-protected data structure). Otherwise there can be use-after-free BUG.
There are lots of cases of using pid_task() in Linux kernel sources (e.g. in posix_timer_event()).
For example:
rcu_read_lock();
/* search through the global namespace */
task = pid_task(find_pid_ns(pid_num, &init_pid_ns), PIDTYPE_PID);
if (task)
printk(KERN_INFO "1. pid: %d, state: %#lx\n",
pid_num, task->state); /* valid task dereference */
rcu_read_unlock(); /* after it returns - task pointer becomes invalid! */
if (task)
printk(KERN_INFO "2. pid: %d, state: %#lx\n",
pid_num, task->state); /* may be successful,
* but is buggy (task dereference is INVALID!) */
Find out more about RCU API from Kernel.org
P.S. also you can just use the special API functions like find_task_by_pid_ns() and find_task_by_vpid() under the rcu_read_lock().
The first one is for searching through the particular namespace:
task = find_task_by_pid_ns(pid_num, &init_pid_ns); /* e.g. init namespace */
The second one is for searching through the namespace of current task.