Post

[Linux] task_struct

개요

Linux kernel에서는 모든 process와 thread를 Task라는 단위로 처리하게 됩니다. Kernel 단에서 아래의 함수가 호출되면서 생성되게 됩니다.

  • 예전: _do_fork()
  • 현재: kernel_clone()

💡 즉, User에서 호출하는 fork(), clone(), pthread_create() 같은 함수를 호출하게 되더라도 전부 Kernel에 존재하는 함수를 거치게 되는 것입니다!

해당 함수들에서는 task_struct라는 구조체를 만들어서 관리하게 됩니다.

task_struct

task_struct의 구조는 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
struct task_struct {
#ifdef CONFIG_THREAD_INFO_IN_TASK
	/*
	 * For reasons of header soup (see current_thread_info()), this
	 * must be the first element of task_struct.
	 */
	struct thread_info		thread_info;
#endif
	unsigned int			__state;

	/* saved state for "spinlock sleepers" */
	unsigned int			saved_state;

	/*
	 * This begins the randomizable portion of task_struct. Only
	 * scheduling-critical items should be added above here.
	 */
	randomized_struct_fields_start

	void				*stack;
	refcount_t			usage;
	/* Per task flags (PF_*), defined further below: */
	unsigned int			flags;
	unsigned int			ptrace;

	...

	pid_t				pid;
	pid_t				tgid;

#ifdef CONFIG_STACKPROTECTOR
	/* Canary value for the -fstack-protector GCC feature: */
	unsigned long			stack_canary;
#endif
	/*
	 * Pointers to the (original) parent process, youngest child, younger sibling,
	 * older sibling, respectively.  (p->father can be replaced with
	 * p->real_parent->pid)
	 */

	/* Real parent process: */
	struct task_struct __rcu	*real_parent;

	/* Recipient of SIGCHLD, wait4() reports: */
	struct task_struct __rcu	*parent;

	/*
	 * Children/sibling form the list of natural children:
	 */
	struct list_head		children;
	struct list_head		sibling;
	struct task_struct		*group_leader;

	...

	struct mm_struct		*mm;

	...

여기서 중요한 멤버 변수는 다음과 같습니다.

  • pid_t pid: 프로세스의 pid를 식별하는 값
  • pid_t tgid: thread의 그룹아이디
  • struct task_struct __rcu *real_parent: 자신을 생성한 부모 Task 포인터
  • struct task_struct __rcu *parent: 현재 부모 Task 포인터
  • struct mm_struct *mm: mm_struct는 유저 공간의 텍스트, 데이터, 스택 등의 영역 위치와 메타데이터가 존재

mm_struct

다음과 같이 멤버 이름만 봐도 알 수 있지만 code, data, heap(brk)의 주소 시작 값을 담고 있습니다.

1
2
3
4
5
6
struct mm_struct {
	...
	unsigned long start_code, end_code, start_data, end_data;
	unsigned long start_brk, brk, start_stack;
	unsigned long arg_start, arg_end, env_start, env_end;
	...

정리

Linux Kernel에서 결국 모든 Task는 현재 기준 kernel_clone 함수를 통해 task_struct 구조체가 생성되어 관리가 되는 것을 확인할 수 있습니다.

This post is licensed under CC BY 4.0 by the author.