System call creation process

Windows operation process

Function analysis

Create process

Under Windows, a process can be created by calling createp process() system. The parameters passed in and their meanings are as follows

BOOL CreateProcess(  
 LPCTSTR lpApplicationName, // Application name  
 LPTSTR lpCommandLine, // Command line string  
 LPSECURITY_ATTRIBUTES lpProcessAttributes, // Security properties of the process  
 LPSECURITY_ATTRIBUTES lpThreadAttributes, // Thread security properties  
 BOOL bInheritHandles, // Inherit the properties of the parent process  
 DWORD dwCreationFlags, // Create flag  
 LPVOID lpEnvironment, // Points to a newly created environment block
 LPCTSTR lpCurrentDirectory, // Pointer to the current directory name  
 LPSTARTUPINFO lpStartupInfo, // Information passed to the new process  
 LPPROCESS_INFORMATION lpProcessInformation // Information returned by the new process  
);  

About the structure of lpProcessInformation

typedef struct _PROCESS_INFORMATION {
    HANDLE hProcess;//The handle of the process can be used to end the process. The handle must have PROCESS_TERMINATE access.
    HANDLE hThread;
    DWORD  dwProcessId;
    DWORD  dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;

Destruction process

The destruction process can adopt the following two methods

void ExitProcess(
  UINT uExitCode
);
BOOL WINAPI TerminateProcess(
    __in  HANDLE hProcess,//Handle to the process to terminate
    __in  UINT uExitCode//The exit code that will be used by processes and threads that terminate as a result of this call.
);
//Handle must have PROCESS_TERMINATE access.

There is a process with the same name. Using TerminateProcess() to destroy it will fail

Linux operating system

summary

Create process commands for linux

  • fork() copies all the resources of the parent process to the child process;
  • vfork() divides the parent process by mm_ Copy all the resources of struct to the child process;
  • clone() is through CLONE_XXX specifies which resources to copy from the parent process to the child process

Fork, VFORK and clone are essentially to the kernel_ The call of clone function is different in the parameters passed in

A successful fork() call returns 0. In the parent process, fork() returns the pid of the child process. If an error occurs, fork returns a negative value. The following similarities exist between parent and child processes

  1. The pid of the child process is newly allocated, which is different from the parent process.

  2. The ppid of the child process will be set as the pid of the parent process.

  3. The resource statistics in the child process will be cleared.

  4. Any pending signals are cleared and will not be inherited by the child process (see Chapter 9).

  5. No file locks are inherited by child processes.

fork

Check the commit record cad6967ac10843a70842cd39c7b53412901dd21f and find it in V5 10-rc1 replace the original_ do_fork replaced with kernel_clone

#ifdef __ARCH_WANT_SYS_FORK
SYSCALL_DEFINE0(fork)//Refer to kernel / sys for system call definition C 0 means that the fork system call requires 0 parameters
{
#ifdef CONFIG_MMU
	struct kernel_clone_args args = {
		.exit_signal = SIGCHLD,
	};

	return kernel_clone(&args);
#else
	/* can not support in nommu mode */
	return -EINVAL;
#endif
}
#endif

The fork function returns twice, one in the parent process and the other in the child process. If the return value is 0, it indicates that it is a child process; If the return value is a positive number, it indicates that it is the parent process

vfork

#ifdef __ARCH_WANT_SYS_VFORK
SYSCALL_DEFINE0(vfork)
{
	struct kernel_clone_args args = {
		.flags		= CLONE_VFORK | CLONE_VM,
		.exit_signal	= SIGCHLD,
	};

	return kernel_clone(&args);
}
#endif

kernel_clone

pid_t kernel_clone(struct kernel_clone_args *args)//pid_t returns the process number for the process number type function
{
	u64 clone_flags = args->flags;
	struct completion vfork;
	struct pid *pid;
	struct task_struct *p; //Create process descriptor structure pointer
	int trace = 0;
	pid_t nr; 

	/*
	 * For legacy clone() calls, CLONE_PIDFD uses the parent_tid argument
	 * to return the pidfd. Hence, CLONE_PIDFD and CLONE_PARENT_SETTID are
	 * mutually exclusive. With clone3() CLONE_PIDFD has grown a separate
	 * field in struct clone_args and it still doesn't make sense to have
	 * them both point at the same memory location. Performing this check
	 * here has the advantage that we don't need to have a separate helper
	 * to check for legacy clone().
	 */
	if ((args->flags & CLONE_PIDFD) &&
	    (args->flags & CLONE_PARENT_SETTID) &&
	    (args->pidfd == args->parent_tid))
		return -EINVAL;

	/*
	 * Determine whether and which event to report to ptracer.  When
	 * called from kernel_thread or CLONE_UNTRACED is explicitly
	 * requested, no event is reported; otherwise, report if the event
	 * for the type of forking is enabled.
	 */
	if (!(clone_flags & CLONE_UNTRACED)) {
		if (clone_flags & CLONE_VFORK)
			trace = PTRACE_EVENT_VFORK;
		else if (args->exit_signal != SIGCHLD)
			trace = PTRACE_EVENT_CLONE;
		else
			trace = PTRACE_EVENT_FORK;

		if (likely(!ptrace_event_enabled(current, trace)))
			trace = 0;
	}
    
    
    // Copy the process descriptor and return the created task_ Pointer to struct
	p = copy_process(NULL, trace, NUMA_NO_NODE, args);
	
   /*add_latent_entropy()See Linux / random H is equivalent to add_device_randomness() is used to generate random numbers
    *Linux The kernel uses entropy to describe the randomness of data
    *Linux The kernel maintains an entropy pool to collect ambient noise from device drivers and other sources.
    *It can generate true random number sequence.
    */
    add_latent_entropy();
    
    //IS_ERR() is actually judging the pointer
	if (IS_ERR(p))
		return PTR_ERR(p);   //Then convert the pointer to long type data

	/*
	 * Do this prior waking up the new thread - the thread pointer
	 * might get invalid after that point, if the thread exits quickly.
	 */
	trace_sched_process_fork(current, p);
    
    // Get the pid in the newly created process descriptor
	pid = get_task_pid(p, PIDTYPE_PID);//Used to find the corresponding struct pid according to task and pid type
	nr = pid_vnr(pid);//The return value is pid_ A variable of type T, which represents the global process number of the obtained process. The parameter pid is a pointer variable of type struct pid

	if (clone_flags & CLONE_PARENT_SETTID)
		put_user(nr, args->parent_tid);
    
    //If vfork is used, initialize vfork to complete processing information and ensure that the parent process runs after
	if (clone_flags & CLONE_VFORK) {
		p->vfork_done = &vfork;
		init_completion(&vfork);
		get_task_struct(p);
	}
    
    // Add the subprocess to the queue of the scheduler, so that the subprocess has the opportunity to get the CPU
	wake_up_new_task(p);

	//fork is completed and the child process will start running
	if (unlikely(trace))
		ptrace_event_pid(trace, pid);
    // If it is vfork, insert the parent process into the waiting queue and suspend the parent process until the child process releases its own memory space
	// Ensure that the child process runs first with the parent process
    if (clone_flags & CLONE_VFORK) {
		if (!wait_for_vfork_done(p, &vfork))
			ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid);
	}

	put_pid(pid);//Used to free the Cache space occupied by the process
	return nr;
}

copy_process

  1. Execute dup_task_struct(), copy the current process task_struct
  2. Check whether the number of processes exceeds the maximum allowed by the system (32678 by default)
  3. Execute sched_fork(), set the scheduler related information, and set the task process status to TASK_RUNNING and allocating CPU resources
  4. Execute copy_xxx(), copy the files, fs, mm, io, sighand, signal and other information of the process
  5. Execute copy_thread_tls(), copy the kernel stack information of the child process
  6. Execute alloc_pid(), assign a new pid to the new process

Reference link

https://www.cnblogs.com/sky-heaven/p/5715066.html

https://blog.csdn.net/notbaron/article/details/80033417

https://www.coolcou.com/linux-kernel/linux-process-management-kernel-api

https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa

https://github.com/torvalds/linux

Keywords: Linux Windows Operating System

Added by Gibb Boy on Wed, 05 Jan 2022 20:35:19 +0200