Tracing Parent process and child process by gdb
2015-04-05 09:02
671 查看
Chapter 1 Environment
Ubuntu 14.10
Linux Kernel 3.18.6
Chapter 2 Debugging fork
When I set breakpoints as what video shows, I found that I was totally interrupted. At last, I acknowledged that I set breakpoints when the menu system started. That's funny.
I was totally interrupted at the process of kernel initialization, and the kernle started after 30 minutes.
Breakpoints:
sys_clone
do_fork
dup_task_struct
copy_process
copy_thread
ret_from_fork
alloc_thread_info_node
Chapter 3 Analysis
First, it is do_fork. When we are running do_fork, it will judge the situation to prevent from the dangerous process. Then it starts the copy_process.
copy_process is called by do_fork, whose main function is that complish the data structure of process, the initialization of various kinds of resources. Initialization can be relocated, or share with the parent process. It depends on the parameter of CLONE.
Reference:http://blog.csdn.net/bullbat/article/details/7088484
However, I found that there are two copy_process, the first one is showed at breakpoint 4, and the second is at breakpoint 3.
dup_task_struct:
Calling dup_task_struct to make a new memory stack for new process. It is defined in kerenel/fork.c. This function calls copy_process. The process is running. From the
name of function dup we know that the descriptor of the child process is as same as parent process.
Reference:http://www.cnblogs.com/hanyan225/archive/2011/07/09/2101962.html
copy_thread:
These code just like the mini kernel myKernel, which is setuped at second week course. It copied itself three times to make four proccess, and then run respectively. Nevertheless, the four proccesses are equal. But the proccesses made by fork are not equal.
There is key point which points out the method of creating the child proccess.
这个函数就是复制父进程堆栈的内容到子进程的堆栈中去,并且设置一下子进程的task_struct内容,我们重点的也就是子进程系统堆栈的分析部分。特别是这句代码
P是新建的进程的task_struct结构,他是在新分配的二个页面(THREAD_SIZE)的最低下,而pt_regs是系统的保存系统调用时或者中断时寄存器的数据结构,如果P+THREAD_SIZE就代表子进程的堆栈的最顶端也就是ESP,如果转换成pt_regs结构再减去1,这里的计算结果实在是太模糊,,如果按照pt_regs结构减掉1的话就是分配了一个pt_regs,那也就是说《Linux内核情景分析》书中302页的图。这个图的理解是从系统空间堆栈中减掉一个pt_regs结构,实际上变相分配堆栈给pt_regs了。
参考资料:http://blog.chinaunix.net/uid-7960587-id-2035513.html
ret_from_fork:
对于fork来说,父子进程共享同一段代码空间,所以给人的感觉好像是有两次返回,其实对于调用fork的父进程来说,如果fork出来的子进程没有得到 调度,那么父进程从fork系统调用返回,同时分析sys_fork知道,fork返回的是子进程的id。再看fork出来的子进程,由 copy_process函数可以看出,子进程的返回地址为ret_from_fork(和父进程在同一个代码点上返回),返回值直接置为0。所以当子进
程得到调度的时候,也从fork返回,返回值为0。
关键注意两点:1.fork返回后,父进程或子进程的执行位置。(首先会将当前进程eax的值做为返回值)2.两次返回的pid存放的位置。(eax中)
参考资料:http://blog.csdn.net/guichen83/article/details/4160697
然后便是无法追踪的内核部分。具体见第五份作业。
Chapter 4 Conclusion
Proccess:
Copy the relative resources and proccess structure of parent proccess to create child proccess. Then it set pid as 0 to distinguish child and parent proccess. What a coincindence. My work of system call if fork. At that time, the program seems to run twice.
This week I have got the answer. At last, the fork function will have something interesting when it meets up with printf. You can learn more detail on the following interviewing problem.
Chapter 5 Extended Material: Two interviewing problem about fork(The second website is recommanded).
http://www.oschina.net/question/195301_62902 http://blog.chinaunix.net/uid-26495963-id-3150121.html
Appendix
Luxuan + Writen by the author, Please let me know if you want to take it as a reference + Linux Kernel Analyzation a course of MOOC website:http://mooc.study.163.com/course/USTC-1000029000
Ubuntu 14.10
Linux Kernel 3.18.6
Chapter 2 Debugging fork
When I set breakpoints as what video shows, I found that I was totally interrupted. At last, I acknowledged that I set breakpoints when the menu system started. That's funny.
I was totally interrupted at the process of kernel initialization, and the kernle started after 30 minutes.
Breakpoints:
sys_clone
do_fork
dup_task_struct
copy_process
copy_thread
ret_from_fork
alloc_thread_info_node
Chapter 3 Analysis
First, it is do_fork. When we are running do_fork, it will judge the situation to prevent from the dangerous process. Then it starts the copy_process.
copy_process is called by do_fork, whose main function is that complish the data structure of process, the initialization of various kinds of resources. Initialization can be relocated, or share with the parent process. It depends on the parameter of CLONE.
Reference:http://blog.csdn.net/bullbat/article/details/7088484
However, I found that there are two copy_process, the first one is showed at breakpoint 4, and the second is at breakpoint 3.
dup_task_struct:
Calling dup_task_struct to make a new memory stack for new process. It is defined in kerenel/fork.c. This function calls copy_process. The process is running. From the
name of function dup we know that the descriptor of the child process is as same as parent process.
Reference:http://www.cnblogs.com/hanyan225/archive/2011/07/09/2101962.html
copy_thread:
*childregs = *current_pt_regs(); childregs->ax = 0; if (sp) childregs->sp = sp; p->thread.ip = (unsigned long) ret_from_fork; task_user_gs(p) = get_user_gs(current_pt_regs()); p->thread.io_bitmap_ptr = NULL; tsk = current;
These code just like the mini kernel myKernel, which is setuped at second week course. It copied itself three times to make four proccess, and then run respectively. Nevertheless, the four proccesses are equal. But the proccesses made by fork are not equal.
There is key point which points out the method of creating the child proccess.
int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, struct task_struct *p)
{
struct pt_regs *childregs = task_pt_regs(p);
struct task_struct *tsk;
int err;
p->thread.sp = (unsigned long) childregs;
p->thread.sp0 = (unsigned long) (childregs+1);
memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
if (unlikely(p->flags & PF_KTHREAD)) {
/* kernel thread */
memset(childregs, 0, sizeof(struct pt_regs));
p->thread.ip = (unsigned long) ret_from_kernel_thread;
task_user_gs(p) = __KERNEL_STACK_CANARY;
childregs->ds = __USER_DS;
childregs->es = __USER_DS;
childregs->fs = __KERNEL_PERCPU;
childregs->bx = sp; /* function */
childregs->bp = arg;
childregs->orig_ax = -1;
childregs->cs = __KERNEL_CS | get_kernel_rpl();
childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_FIXED;
p->thread.io_bitmap_ptr = NULL;
return 0;
}
*childregs = *current_pt_regs(); childregs->ax = 0; if (sp) childregs->sp = sp; p->thread.ip = (unsigned long) ret_from_fork; task_user_gs(p) = get_user_gs(current_pt_regs()); p->thread.io_bitmap_ptr = NULL; tsk = current;
err = -ENOMEM;
if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
IO_BITMAP_BYTES, GFP_KERNEL);
if (!p->thread.io_bitmap_ptr) {
p->thread.io_bitmap_max = 0;
return -ENOMEM;
}
set_tsk_thread_flag(p, TIF_IO_BITMAP);
}
err = 0;
/*
* Set a new TLS for the child thread?
*/
if (clone_flags & CLONE_SETTLS)
err = do_set_thread_area(p, -1,
(struct user_desc __user *)childregs->si, 0);
if (err && p->thread.io_bitmap_ptr) {
kfree(p->thread.io_bitmap_ptr);
p->thread.io_bitmap_max = 0;
}
return err;
}
这个函数就是复制父进程堆栈的内容到子进程的堆栈中去,并且设置一下子进程的task_struct内容,我们重点的也就是子进程系统堆栈的分析部分。特别是这句代码
((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
P是新建的进程的task_struct结构,他是在新分配的二个页面(THREAD_SIZE)的最低下,而pt_regs是系统的保存系统调用时或者中断时寄存器的数据结构,如果P+THREAD_SIZE就代表子进程的堆栈的最顶端也就是ESP,如果转换成pt_regs结构再减去1,这里的计算结果实在是太模糊,,如果按照pt_regs结构减掉1的话就是分配了一个pt_regs,那也就是说《Linux内核情景分析》书中302页的图。这个图的理解是从系统空间堆栈中减掉一个pt_regs结构,实际上变相分配堆栈给pt_regs了。
参考资料:http://blog.chinaunix.net/uid-7960587-id-2035513.html
ret_from_fork:
对于fork来说,父子进程共享同一段代码空间,所以给人的感觉好像是有两次返回,其实对于调用fork的父进程来说,如果fork出来的子进程没有得到 调度,那么父进程从fork系统调用返回,同时分析sys_fork知道,fork返回的是子进程的id。再看fork出来的子进程,由 copy_process函数可以看出,子进程的返回地址为ret_from_fork(和父进程在同一个代码点上返回),返回值直接置为0。所以当子进
程得到调度的时候,也从fork返回,返回值为0。
关键注意两点:1.fork返回后,父进程或子进程的执行位置。(首先会将当前进程eax的值做为返回值)2.两次返回的pid存放的位置。(eax中)
参考资料:http://blog.csdn.net/guichen83/article/details/4160697
然后便是无法追踪的内核部分。具体见第五份作业。
Chapter 4 Conclusion
Proccess:
Copy the relative resources and proccess structure of parent proccess to create child proccess. Then it set pid as 0 to distinguish child and parent proccess. What a coincindence. My work of system call if fork. At that time, the program seems to run twice.
This week I have got the answer. At last, the fork function will have something interesting when it meets up with printf. You can learn more detail on the following interviewing problem.
Chapter 5 Extended Material: Two interviewing problem about fork(The second website is recommanded).
http://www.oschina.net/question/195301_62902 http://blog.chinaunix.net/uid-26495963-id-3150121.html
Appendix
Luxuan + Writen by the author, Please let me know if you want to take it as a reference + Linux Kernel Analyzation a course of MOOC website:http://mooc.study.163.com/course/USTC-1000029000
相关文章推荐
- Use Named Pipes and Shared Memory for inter process communication with a child process or two
- Center parent div with dynamic and set width child divs
- 关于APACHE进程重启问题的分析 Parent: child process exited with status 3221225477 -- Restarting
- (FW: From MSDN)Creating a Child Process with Redirected Input and Output
- phantomjs - node.js parse child process output line by line (spawn) - Stack Overflow
- How Tomcat works之第十一章之Parent and Child
- org.neo4j.kernel.StoreLockException: Store and its lock file has been locked by another process
- the question regarding "Parent and Child Latches", version 11.1.0.7
- Node.JS 5.ChildProcessAndFileSystem
- Parent and child cursors in the library cache
- Sql级联查询递归查询start with 。。。connect by prior child=parent
- Analysing the ASM code of a simple sample of C programming language at Linux Platform by GCC and GDB
- [Chapter 3 Process]Practice 3.2 Including the initial parent process, how many processes are created by the program shown in Figure?
- navigate and process Analysis Services by powershell
- 服务启动Apache服务,错误Parent: child process exited with status 3 -- Aborting.解决
- Creating a Child Process with Redirected Input and Output
- Parent-Child Data Manipulations with GridView and DetailsView control
- crontab “tput: No value for $TERM and no -T specified ” error logged by CRON process
- [Chapter 3 Process]Practice 3.12 Including the initial parent process, how many processes are created by the program shown in Figure 3.32?
- Creating a Child Process with Redirected Input and Output