시스템콜 : 인자오류 철저하게 검사함 > 그래야 커널 손상 down
유저 fork() -> ARM64_sys_clone() -> kernel_clone() -> copy_process()
>
debug/tracing/cat avilabe_filter_function | grep copy_process
>> 유저가 fork() 로 process 생성 할때 벌어지는일 grep
그전에.. 계층구조부터 보자면
pid
2571 bash // 부모 ,기본
2720 a.out // 자식 , 프로그램 실행명 // 이 코드에서 fork() 실행
2721 a.out // fork()로 만든 자식 , 순차적임
자, 이제 ftraceLog로 아까 grep 한걸 보자.
bash-2571 copy_process() <- kernel_clone() // bash 에서 kernel_clone() 이 copy_process를 호출했구나.
<stack trace> // 이때의 스택 흔적은..
copy_process()
kernel_clone()
ARM64_sys_clone() // 2번, 스택 구조이므로
invoke_syscall // 1. 시스템콜
// 맨위에서와 같이 순서대로 잘된것을 확인
"
"
a.out-2720 copy_process() <- kernel_clone() // a.out 에서 fork()에의해 자식 생성!
/*
echo(그외 명령어) 함수명 > 파일명 // 덮어쓰기
echo 함수명 >> 파일명 // 이어쓰기
// ' * ' : wildcard , hi * : hi가 포함되어있는 모든 파일 찾음
*/
/*
process 죽이기 : kill -9 pid // 9 : signal
> sig=9 한다음 do_exit()
자식) signal_generated sig=17
부모) signal_delival sig = 17
<> kill 이 아닌 함수 내부에서 exit() 를 한다면,, 따로 sig 를 보내지않고 종료
이때 wakeup_parent + 0x0 // 0xc00808f8d0 을 하는데.. 이걸 확인하기 위해
/linuxSrc/out/ objdump -D vmlinux // vmlinux 디스어셈블 : 최종실행파일을 어셈블리로 확인
> 이때 ARM 아키텍쳐는 pipeline 에 의해 -4 를 해서 봐야함
// 0xc00808f8d0 > 0xc00808f8cc
*/
1. pid를 다르게 (순차적) , 이름은 같게 한다음 // sched_process_fork
2. task_rename 으로 자식의 이름을 정의함 // bash -> a.out
*/
커널이 thread를 만들때
thread (~=demon) : 모두 커널에서 만들어지며, backgroun 동작, memory, power 제어
// background : ./a.out& > ./a.out 이 동작 하면서도 나는 명령어 칠 수 있음 ( bash + a.out)
kthreadd() : thread 생성 handler // ps -axjf
/*
대표 thread
1. kworker thread : work Queue를 실행
> 핸들러 : worker_thread()
2. ksoftirqd : soft interrupt 처리
> ksoftirqd/1 : 1번 cpu
3. irq/인터럽트번호 - 이름 : interrupt 번호 후반부 처리
*/
thread_create ( Handler함수지정 , , , , ) // 스케쥴러 queue 에들어가고
> handler : 쓰레드의 전반적인 행동,목표
> threadfn 핸들러 : int ( *threadfn ) (void* data)
// threadfn 이라는 이름의 void * data 가 인자로 들어가며 int로 반환하는 함수의 주소를 저장하는 함수포인터
// int (*operations[3])(int, int) = {add, sub, mul}; 함수포인터 배열 ( 함수를 여러개 배열로저장)
/*
// 콜백 함수: 두 정수를 받아 연산을 수행
void execute_operation(int (*operation)(int, int), int x, int y) {
printf("결과: %d\n", operation(x, y));
}
// 연산 함수들
int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }
int main() {
execute_operation(add, 3, 7); // add(3, 7) → 출력: 결과: 10
execute_operation(mul, 3, 7); // mul(3, 7) → 출력: 결과: 21
return 0;
}
*/
/*
(void * data) 를 인자로 받으면
// 구조체안에 char , int, 함수포인터 등등 다 넣어두고
typedef struct {
char name[20];
int age;
} Person;
// 값을 넣은 후 함수로 값을 void 형태로 전달
int main() {
Person person = {"홍길동", 25};
// 구조체 포인터를 void*로 전달
print_person((void*)&person);
return 0;
}
// 여기서 마지막에도 void 로 받아온 후
// Person 형태로 바꿔주면 뭐가있던 다 받아낼수있음
void print_person(void* data) {
Person* p = (Person*)data; // void* → Person* 캐스팅
printf("이름: %s, 나이: %d\n", p->name, p->age);
}
*/
kernel_kthread() , kernel_clone() // 스케쥴러에 의한 함수실행 > 프로세스 생성