我在一本教科书中了解到,当进程变成僵尸时,Linux会保留流程描述符,直到将来的父级验证退出状态为止。我理解过程描述符有两个结构:板条中的task_struct和内核堆栈中的thread_info (忘记x86)。
我正在阅读源代码的< do_exit() /exit.c>部分,但我不太清楚内核堆栈是在哪里被释放的。我可以发现,exit_notify()将进程的状态更改为僵尸。其余的代码看起来都是关于清理锁之类的,直到schedule()为止。
我似乎找不到释放内核堆栈的部分?还是我不理解内核堆栈是如何工作的?或者thread_info被认为根本不被保存,并且在变成僵尸之前已经和内核堆栈一起被丢弃了?
到底是怎么回事?
发布于 2021-01-12 16:41:02
让我们深入研究任务的结束:
有两个系统调用:exit_group()和exit(),它们都将转到do_exit(),它将执行以下任务。
deleting
PF_EXTING,这意味着任务是del_timer_sync()
exit_mm(), exit_sem(), __exit_fs()和其他人从定时器中释放的任务描述符-- ref count
exit_code to _exit()/exit_group()或error
H 119调用exit_notify() f 121H 122更新父和子H 223H 124检查exit_signal,发送SIGCHLD
EXIT_DEAD,调用EXIT_ZOMBIE
PF_DEAD
任务标志为PF_DEAD。
schedule()
我们需要僵尸状态,因为父程序可能需要使用这些文件描述符,所以我们不能在第一次删除所有内容。父任务将需要使用类似于wait()的东西来检查子任务是否已死。在wait()之后,僵尸是时候完全由release_task()发布了
如果任务被跟踪,则
nr_threads--ptrace_children列表中删除__exit_signal(),删除所有挂起的信号并释放signal_struct描述符,以及exit_itimers()删除所有计时器<代码>H 258<代码>H 159调用<代码>D60调用信号处理程序H 261H 162调用<代码>D63D63D69以从< list >D70和PIDTYPE_TGID
call <代码>D74中删除任务描述符。调用sched_exit()来调度父级的时间段调用put_task-struct()以减少计数器,并释放内存和任务描述符然后,我们把它全部释放。
https://stackoverflow.com/questions/65652882
复制相似问题