[[PageOutline]] = 10/12 = == trace getpid() syscall with GDB == * windell57:x86_64 s0711489$ gdb {{{ (gdb) set logging file gdb.getpid.log (gdb) set logging on Copying output to gdb.getpid.log. (gdb) file vmlinux Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done. (gdb) b sys_getpid Breakpoint 1 at 0xffffffff81048ce4: file kernel/timer.c, line 1344. (gdb) target remote localhost:8864 Remote debugging using localhost:8864 0xffffffff810097a9 in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49 49 asm volatile("sti; hlt": : :"memory"); (gdb) c Continuing. Breakpoint 1, sys_getpid () at kernel/timer.c:1344 }}} * => attachment:gdb.getpid.log * on VM guest * s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ ./getpid {{{ getpid() -> 2143 }}} == trace log with source list and print data == * windell57:x86_64 s0711489$ gdb {{{ (gdb) file vmlinux Reading symbols from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/vmlinux...(no debugging symbols found)...done. (gdb) b sys_getpid Breakpoint 1 at 0xffffffff81048ce4: file kernel/timer.c, line 1344. (gdb) target remote localhost:8864 Remote debugging using localhost:8864 0xffffffff810097a9 in native_safe_halt () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/irqflags.h:49 49 asm volatile("sti; hlt": : :"memory"); (gdb) c Continuing. Breakpoint 1, sys_getpid () at kernel/timer.c:1344 1344 { (gdb) bt #0 sys_getpid () at kernel/timer.c:1344 #1 0xffffffff810029eb in ?? () #2 0x0000000000000246 in ?? () #3 0x00007fff70d418e0 in ?? () #4 0x00007f6c11b19210 in ?? () #5 0x00007f6c11b05300 in ?? () #6 0x0000000000000027 in ?? () #7 0x0000000000000000 in ?? () (gdb) l 1339 * which case the tgid is the same in all threads of the same group. 1340 * 1341 * This is SMP safe as current->tgid does not change. 1342 */ 1343 SYSCALL_DEFINE0(getpid) 1344 { 1345 return task_tgid_vnr(current); 1346 } 1347 1348 /* (gdb) s 1345 return task_tgid_vnr(current); (gdb) get_current () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14 14 return percpu_read_stable(current_task); (gdb) l 9 10 DECLARE_PER_CPU(struct task_struct *, current_task); 11 12 static __always_inline struct task_struct *get_current(void) 13 { 14 return percpu_read_stable(current_task); 15 } 16 17 #define current get_current() 18 (gdb) bt #0 get_current () at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14 #1 sys_getpid () at kernel/timer.c:1345 #2 0xffffffff810029eb in ?? () #3 0x0000000000000246 in ?? () #4 0x00007fff63204890 in ?? () #5 0x00007fc615a98210 in ?? () #6 0x00007fc615a84300 in ?? () #7 0x0000000000000027 in ?? () #8 0x0000000000000000 in ?? () (gdb) p current_task Cannot access memory at address 0xb540 (gdb) ptype current_task type = struct task_struct { (snip) (gdb) s sys_getpid () at kernel/timer.c:1344 1344 { (gdb) l 1339 * which case the tgid is the same in all threads of the same group. 1340 * 1341 * This is SMP safe as current->tgid does not change. 1342 */ 1343 SYSCALL_DEFINE0(getpid) 1344 { 1345 return task_tgid_vnr(current); 1346 } 1347 1348 /* (gdb) bt #0 sys_getpid () at kernel/timer.c:1344 #1 0xffffffff810029eb in ?? () #2 0x0000000000000246 in ?? () #3 0x00007fff63204890 in ?? () #4 0x00007fc615a98210 in ?? () #5 0x00007fc615a84300 in ?? () #6 0x0000000000000027 in ?? () #7 0x0000000000000000 in ?? () (gdb) s 1345 return task_tgid_vnr(current); (gdb) s task_tgid_vnr (tsk=0xffff88001bbe5880) at include/linux/sched.h:1606 1606 { (gdb) l 1601 } 1602 1603 pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); 1604 1605 static inline pid_t task_tgid_vnr(struct task_struct *tsk) 1606 { 1607 return pid_vnr(task_tgid(tsk)); 1608 } 1609 1610 (gdb) bt #0 task_tgid_vnr (tsk=0xffff88001bbe5880) at include/linux/sched.h:1606 #1 0xffffffff81048cf6 in sys_getpid () at kernel/timer.c:1345 #2 0xffffffff810029eb in ?? () #3 0x0000000000000246 in ?? () #4 0x00007fff63204890 in ?? () #5 0x00007fc615a98210 in ?? () #6 0x00007fc615a84300 in ?? () #7 0x0000000000000027 in ?? () #8 0x0000000000000000 in ?? () (gdb) p tsk $2 = (struct task_struct *) 0xffff88001bbe5880 (gdb) ptype tsk type = struct task_struct { (snip) pid_t pid; pid_t tgid; (snip) struct task_struct *group_leader; struct list_head ptraced; struct list_head ptrace_entry; struct pid_link pids[3]; (snip) (gdb) ptype tsk->group_leader->pids type = struct pid_link { struct hlist_node node; struct pid *pid; } [3] (snip) (gdb) s 1607 return pid_vnr(task_tgid(tsk)); (gdb) 1606 { (gdb) 1607 return pid_vnr(task_tgid(tsk)); (gdb) pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:444 444 { (gdb) bt #0 pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:444 #1 0xffffffff81048783 in task_tgid_vnr (tsk=) at include/linux/sched.h:1607 #2 0xffffffff81048cf6 in sys_getpid () at kernel/timer.c:1345 #3 0xffffffff810029eb in ?? () #4 0x0000000000000246 in ?? () #5 0x00007fff63204890 in ?? () #6 0x00007fc615a98210 in ?? () #7 0x00007fc615a84300 in ?? () #8 0x0000000000000027 in ?? () #9 0x0000000000000000 in ?? () (gdb) l 439 } 440 return nr; 441 } 442 443 pid_t pid_vnr(struct pid *pid) 444 { 445 return pid_nr_ns(pid, current->nsproxy->pid_ns); 446 } 447 EXPORT_SYMBOL_GPL(pid_vnr); 448 (gdb) ptype pid type = struct pid { atomic_t count; unsigned int level; struct hlist_head tasks[3]; struct rcu_head rcu; struct upid numbers[1]; } * (gdb) up #1 0xffffffff81048783 in task_tgid_vnr (tsk=) at include/linux/sched.h:1607 1607 return pid_vnr(task_tgid(tsk)); (gdb) ptype tsk->nsproxy->pid_ns type = struct pid_namespace { struct kref kref; struct pidmap pidmap[128]; int last_pid; struct task_struct *child_reaper; struct kmem_cache *pid_cachep; unsigned int level; struct pid_namespace *parent; struct vfsmount *proc_mnt; struct bsd_acct_struct *bacct; } * (gdb) down #0 pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:444 444 { (gdb) s 445 return pid_nr_ns(pid, current->nsproxy->pid_ns); (gdb) get_current (pid=0xffff88001fb55400) at /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:14 14 return percpu_read_stable(current_task); (gdb) p current_task Cannot access memory at address 0xb540 (gdb) s pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:445 445 return pid_nr_ns(pid, current->nsproxy->pid_ns); (gdb) s 444 { (gdb) 445 return pid_nr_ns(pid, current->nsproxy->pid_ns); (gdb) pid_nr_ns (pid=0xffff88001fb55400, ns=0xffffffff8181bfe0) at kernel/pid.c:431 431 { (gdb) bt #0 pid_nr_ns (pid=0xffff88001fb55400, ns=0xffffffff8181bfe0) at kernel/pid.c:431 #1 0xffffffff81052db6 in pid_vnr (pid=0xffff88001fb55400) at kernel/pid.c:445 #2 0xffffffff81048783 in task_tgid_vnr (tsk=) at include/linux/sched.h:1607 #3 0xffffffff81048cf6 in sys_getpid () at kernel/timer.c:1345 #4 0xffffffff810029eb in ?? () #5 0x0000000000000246 in ?? () #6 0x00007fff63204890 in ?? () #7 0x00007fc615a98210 in ?? () #8 0x00007fc615a84300 in ?? () #9 0x0000000000000027 in ?? () #10 0x0000000000000000 in ?? () (gdb) l 426 return pid; 427 } 428 EXPORT_SYMBOL_GPL(find_get_pid); 429 430 pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) 431 { 432 struct upid *upid; 433 pid_t nr = 0; 434 435 if (pid && ns->level <= pid->level) { (gdb) l 436 upid = &pid->numbers[ns->level]; 437 if (upid->ns == ns) 438 nr = upid->nr; 439 } 440 return nr; 441 } 442 443 pid_t pid_vnr(struct pid *pid) 444 { 445 return pid_nr_ns(pid, current->nsproxy->pid_ns); (gdb) ptype pid type = struct pid { atomic_t count; unsigned int level; struct hlist_head tasks[3]; struct rcu_head rcu; struct upid numbers[1]; } * (gdb) ptype ns type = struct pid_namespace { struct kref kref; struct pidmap pidmap[128]; int last_pid; struct task_struct *child_reaper; struct kmem_cache *pid_cachep; unsigned int level; struct pid_namespace *parent; struct vfsmount *proc_mnt; struct bsd_acct_struct *bacct; } * type = struct upid { int nr; struct pid_namespace *ns; struct hlist_node pid_chain; } * (gdb) ptype pid_t type = int (gdb) p ns->level $5 = 0 (gdb) p pid->level $6 = 0 (gdb) p ns->level <= pid->level $7 = 1 (gdb) p ns $8 = (struct pid_namespace *) 0xffffffff8181bfe0 (gdb) p &pid->numbers[ns->level] $9 = (struct upid *) 0xffff88001fb55430 (gdb) p (&pid->numbers[ns->level])->ns $10 = (struct pid_namespace *) 0xffffffff8181bfe0 (gdb) info locals upid = nr = (gdb) p nr $11 = (gdb) p (&pid->numbers[ns->level])->nr $12 = 2225 (gdb) s 435 if (pid && ns->level <= pid->level) { (gdb) 431 { (gdb) 435 if (pid && ns->level <= pid->level) { (gdb) 436 upid = &pid->numbers[ns->level]; (gdb) 437 if (upid->ns == ns) (gdb) p upid $13 = (struct upid *) 0xffff88001fb55430 (gdb) s 438 nr = upid->nr; (gdb) p upid->ns == ns $14 = 1 (gdb) p nr $15 = (gdb) p upid->nr $16 = 2225 (gdb) s 441 } (gdb) pid_vnr (pid=) at kernel/pid.c:446 446 } (gdb) s task_tgid_vnr (tsk=) at include/linux/sched.h:1608 1608 } (gdb) sys_getpid () at kernel/timer.c:1346 1346 } (gdb) sys_getpid () at kernel/timer.c:1345 1345 return task_tgid_vnr(current); (gdb) sys_getpid () at kernel/timer.c:1346 1346 } (gdb) }}} * on VM guest * s0711489@ubuntu-lucid64:~/coursework/KernelHack/02$ ./getpid {{{ getpid() -> 2225 }}} === location of functions on source file === * windell57:x86_64 s0711489$ grep percpu_read_stable -r . {{{ (snip) ./arch/x86/include/asm/percpu.h:#define percpu_read_stable(var) percpu_from_op("mov", var, "p" (&(var))) (snip) }}} * windell57:x86_64 s0711489$ grep task_tgid -r . {{{ (snip) ./include/linux/sched.h:static inline struct pid *task_tgid(struct task_struct *task) (snip) }}} * include/linux/sched.h {{{ static inline struct pid *task_tgid(struct task_struct *task) { return task->group_leader->pids[PIDTYPE_PID].pid; } }}} === get_current function === * windell57:02 s0711489$ gcc -E ../linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h -I ~/coursework/KernelHack/linux-2.6.35.14/x86_64/include -I ~/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/ > current.h {{{ In file included from /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/arch/x86/include/asm/percpu.h:44, from ../linux-2.6.35.14/x86_64/arch/x86/include/asm/current.h:5: /home/ugrad/07/s0711489/coursework/KernelHack/linux-2.6.35.14/x86_64/include/linux/kernel.h:733:2: warning: #warning Attempt to use kernel headers from user space, see http: }}} * pre-processed arch/x86/include/asm/current.h {{{ static __always_inline struct task_struct *get_current(void) { return ({ typeof(current_task) pfo_ret__; switch (sizeof(current_task)) { case 1: asm("mov" "b ""%P" "1"",%0" : "=q" (pfo_ret__) : "p" (&(current_task))); break; case 2: asm("mov" "w ""%P" "1"",%0" : "=r" (pfo_ret__) : "p" (&(current_task))); break; case 4: asm("mov" "l ""%P" "1"",%0" : "=r" (pfo_ret__) : "p" (&(current_task))); break; case 8: asm("mov" "q ""%P" "1"",%0" : "=r" (pfo_ret__) : "p" (&(current_task))); break; default: __bad_percpu_size(); } pfo_ret__; }); } }}}