首先看sys/ptrace.h
/bionic/libc/include/sys/ptrace.h
我们在调用的时候使用的是PTRACE_的导出符号,glibc也导出了PT_开头的符号。PTRACE_开头的符号定义在/bionic/libc/kernel/uapi/linux/ptrace.h中
都是int型的数字,回到ptrace函数的定义,头文件中写的是一个不定参数的形式
long ptrace(int, ...);
继续跟进__ptrace函数
__ptrace函数使用汇编实现,其中____NR_ptrace是系统调用号,根据调用号进入kernel层即linux内核的逻辑。此处__NR_ptrace的调用号为26,swi #0 为产生中断,切换到内核模式
内核的实现是在/kernel/ptrace.c中
PTRACE_TRACEME调用
static int ptrace_traceme(void)
382{
383 int ret = -EPERM;
384
385 write_lock_irq(&tasklist_lock);
386 /* Are we already being traced? */
387 if (!current->ptrace) {
388 ret = security_ptrace_traceme(current->parent);
389 /*
390 * Check PF_EXITING to ensure ->real_parent has not passed
391 * exit_ptrace(). Otherwise we don't report the error but
392 * pretend ->real_parent untraces us right after return.
393 */
394 if (!ret && !(current->real_parent->flags & PF_EXITING)) {
395 current->ptrace = PT_PTRACED;
396 __ptrace_link(current, current->real_parent);
397 }
398 }
399 write_unlock_irq(&tasklist_lock);
400
401 return ret;
402}
__ptrace_link函数
void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
38{
39 BUG_ON(!list_empty(&child->ptrace_entry));
40 list_add(&child->ptrace_entry, &new_parent->ptraced);
41 child->