Friday, November 7, 2014

Linux Process Termination

exit(EXIT_SUCCESS or EXIT_FAILURE) terminates a process.  Before that, C lib will perform the following shutdown steps:

- call functions that registered with atexit() or on_exit() calles in reverse order of registration
- flush io streams
- remove temporary files created by the tmpfile() calls

atexit() is a POSIX call that maintain a list of clean up function registered by caller  for process normal termrination.  The clean up functions accepts no parameters and do not return any return code.  If the process is terminated via signal (e.g. kill), the clean up functions will not be called.  The list is also not inherited by child process.

on_exit() is a function equivalent to atexit() in the older version of SUNOS.  Latter version or SUNOS uses atexit().

exit() will finally call the system call _exit() that cleans up kernel resources allocated for the process.  In the kernel level, do_exit() performs the following work:

- set the PF_EXITING flag in task_struct
- remove kernel timer set using del_timer_sync()
- if BSD process accounting is enabled, calls acct_process() to write out the accounting info.
- release and remove resources, including
- __exit_mm() to release mm_struct
- sem_exit() to release IPC semaphore
- __exit_files()/fs()/namespaces()/sighand()to release and remove resources
   - set the exit code
- exit_notify() to send SIGCHLD to parent, reparent the task's child to their threadgroup or to init process.  Also set the task state to TASK_ZOMBIE
- call schedule()

What's left at this point of time is the task structure and the kernel stack and the thread_info in it.

Once the parent or init calls wait(), the above is released via the put_task_struct() function.  The user's process count is decremented.  The task struct is unlinked from the task list.

No comments: