// task information tapset // Copyright (C) 2006 Intel Corporation. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General // Public License (GPL); either version 2, or (at your option) any // later version. %{ #include #include #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) #include #endif #ifndef STAPCONF_TASK_UID #include #endif %} // Return the task_struct representing the current process function task_current:long () %{ /* pure */ THIS->__retvalue = (long)current; %} // Return the parent task_struct of the given task function task_parent:long (task:long) %{ /* pure */ struct task_struct *t = (struct task_struct *)(long)THIS->task; #if defined(STAPCONF_REAL_PARENT) THIS->__retvalue = (long)kread(&(t->real_parent)); #else THIS->__retvalue = (long)kread(&(t->parent)); #endif CATCH_DEREF_FAULT(); %} // Return the state of the given task, one of: // TASK_RUNNING 0 // TASK_INTERRUPTIBLE 1 // TASK_UNINTERRUPTIBLE 2 // TASK_STOPPED 4 // TASK_TRACED 8 // EXIT_ZOMBIE 16 // EXIT_DEAD 32 function task_state:long (task:long) { return @cast(task, "task_struct", "kernel")->state } // Return the name of the given task function task_execname:string (task:long) { return kernel_string(@cast(task, "task_struct", "kernel")->comm) } // Return the process id of the given task function task_pid:long (task:long) { return @cast(task, "task_struct", "kernel")->tgid } // Return the task of the given process id function pid2task:long (pid:long) %{ /* pure */ struct task_struct *t = NULL; pid_t t_pid = (pid_t)(long)THIS->pid; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) struct pid *p_pid = find_get_pid(t_pid); t = pid_task(p_pid, PIDTYPE_PID); put_pid(p_pid); #else rcu_read_lock(); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) t = find_task_by_vpid (t_pid); #else t = find_task_by_pid (t_pid); #endif /* 2.6.24 */ rcu_read_unlock(); #endif /* 2.6.31 */ THIS->__retvalue = (long)t; %} // Return the name of the given process id function pid2execname:string (pid:long) { tsk = pid2task(pid) if (tsk) return task_execname(tsk) return "" } // Return the thread id of the given task function task_tid:long (task:long) { return @cast(task, "task_struct", "kernel")->pid } // Return the group id of the given task function task_gid:long (task:long) %{ /* pure */ struct task_struct *t = (struct task_struct *)(long)THIS->task; #ifdef STAPCONF_TASK_UID THIS->__retvalue = kread(&(t->gid)); CATCH_DEREF_FAULT(); #else /* XXX: We can't easily kread this rcu-protected field. */ /* XXX: no task_gid() in 2.6.28 */ struct cred *cred; rcu_read_lock(); cred = get_task_cred (t); rcu_read_unlock(); THIS->__retvalue = cred->gid; #endif %} // Return the effective group id of the given task function task_egid:long (task:long) %{ /* pure */ struct task_struct *t = (struct task_struct *)(long)THIS->task; #ifdef STAPCONF_TASK_UID THIS->__retvalue = kread(&(t->egid)); CATCH_DEREF_FAULT(); #else /* XXX: We can't easily kread this rcu-protected field. */ /* XXX: no task_egid() in 2.6.28 */ struct cred *cred; rcu_read_lock(); cred = get_task_cred (t); rcu_read_unlock(); THIS->__retvalue = cred->egid; #endif %} // Return the user id of the given task function task_uid:long (task:long) %{ /* pure */ struct task_struct *t = (struct task_struct *)(long)THIS->task; #ifdef STAPCONF_TASK_UID THIS->__retvalue = kread(&(t->uid)); CATCH_DEREF_FAULT(); #else /* XXX: We can't easily kread this rcu-protected field. */ THIS->__retvalue = task_uid (t); #endif %} // Return the effective user id of the given task function task_euid:long (task:long) %{ /* pure */ struct task_struct *t = (struct task_struct *)(long)THIS->task; #ifdef STAPCONF_TASK_UID THIS->__retvalue = kread(&(t->euid)); CATCH_DEREF_FAULT(); #else /* XXX: We can't easily kread this rcu-protected field. */ THIS->__retvalue = task_euid (t); #endif %} // Return the priority value of the given task function task_prio:long (task:long) %{ /* pure */ struct task_struct *t = (struct task_struct *)(long)THIS->task; THIS->__retvalue = kread(&(t->prio)) - MAX_RT_PRIO; CATCH_DEREF_FAULT(); %} // Return the nice value of the given task function task_nice:long (task:long) %{ /* pure */ struct task_struct *t = (struct task_struct *)(long)THIS->task; THIS->__retvalue = kread(&(t->static_prio)) - MAX_RT_PRIO - 20; CATCH_DEREF_FAULT(); %} // Return the scheduled cpu for the given task function task_cpu:long (task:long) { %( kernel_v >= "2.6.22" %? ti = @cast(task, "task_struct", "kernel")->stack %: ti = @cast(task, "task_struct", "kernel")->thread_info %) return @cast(ti, "thread_info", "kernel")->cpu } // Return the number of open file handlers for the given task function task_open_file_handles:long (task:long) %( kernel_v >= "2.6.15" %? %{ /* pure */ int locked = 0; unsigned int count=0, fd, max; struct task_struct *t; struct files_struct *fs; struct fdtable *f; t = (struct task_struct *)(long)THIS->task; fs = kread(&(t->files)); f = kread(&(fs->fdt)); rcu_read_lock(); locked = 1; max = kread(&(f->max_fds)); for (fd = 0; fd < max; fd++) { if ( kread(&(f->fd[fd])) != NULL) count ++; } THIS->__retvalue = count; CATCH_DEREF_FAULT(); if (locked) rcu_read_unlock(); %} %: %{ /* pure */ int locked = 0; unsigned int count=0, fd, max; struct task_struct *t; struct files_struct *f; t = (struct task_struct *)(long)THIS->task; f = kread(&(t->files)); rcu_read_lock(); locked = 1; max = kread(&(f->max_fds)); for (fd = 0; fd < max; fd++) { if ( kread(&(f->fd[fd])) != NULL) count ++; } THIS->__retvalue = count; CATCH_DEREF_FAULT(); if (locked) rcu_read_unlock(); %} %) // Return the maximum number of file handlers for the given task function task_max_file_handles:long (task:long) %( kernel_v >= "2.6.15" %? %{ /* pure */ int locked = 0; struct task_struct *t; struct files_struct *fs; struct fdtable *f; t = (struct task_struct *)(long)THIS->task; fs = kread (&(t->files)); f = kread(&(fs->fdt)); rcu_read_lock(); locked = 1; THIS->__retvalue = kread(&(f->max_fds)); CATCH_DEREF_FAULT(); if (locked) rcu_read_unlock(); %} %: %{ /* pure */ int locked = 0; struct task_struct *t; struct files_struct *f; t = (struct task_struct *)(long)THIS->task; f = kread(&(t->files)); rcu_read_lock(); locked = 1; THIS->__retvalue = kread(&(f->max_fds)); CATCH_DEREF_FAULT(); if (locked) rcu_read_unlock(); %} %)