본문 바로가기
728x90

전체 글255

Strace : debugging tool 시스템 콜/시그널 추적 □ strace - strace는 시스템 콜과 시그널을 추적할 수 있는 일종의 디버깅 툴이다. 만약 프로그램이 지속적인 충돌을 일으키거나, 예상치 못한 동작을 하게되는 경우에도 유용하게 쓰일 수 있다 예를 들면 존재하지 않는 파일을 접근하여 열거나 읽으려할때 strace를 사용하여 문제가 되는 지점을 찾을 수 있다. GNU Debugger(gdb) 와 같은 코드 디버깅같은 세부사항들에 대해서 찾기에는 부적합 할 수 있으나 시스템 콜을 추적하는 툴에있어선 strace가 적합하다. 그리고 코드 디버깅 툴 보다 사용하기가 쉽다. 여기에 몇가지 예를 적고 자세한 사항은 man 페이지를 활용하면 될 것 같다. 각 라인을 잘보면 메모리에 맵핑 시키는것부터 파일을 열고 읽고 쓰고 닫고 하는데 있어 특정 구조체를 호출.. 2016. 9. 11.
메모리(Memory)관리-(2) □ Zone - 노드에 존재하는 물리메모리 중 16MB이하 부분을 관리하기 위해 node의 일부분을 따로 관리할 수 있도록한 자료구조 □ Page frame - 각각의 Zone은 자신에 속해 있는 물리 메모리들을 관리하는데, 이 물리 메모리의 최소단위 - 모든 페이지 프레임 당 하나씩 page 구조체가 존재. 이는 시스템이 부팅되는 순간에 구축되어 역시 물리 메모리 특정 위치에 저장 되는데 이 위치는 mem_map이라는 전역 배열을 통해 접근. 그림처럼 복수 개의 페이지 프레임이 zone을 구성하며 떄에 따라 하나 혹은 그 이상의 zone이 node를 구성하며, 역시 시스템 구조에 따라 하나 혹은 그 이상의 node가 존재하는 것이 리눅스의 전체 물리 메모리 관리 구조. 2016. 9. 9.
포인터와 배열(Pointer & Array) -(1/2) □ 배열의 이름은 배열의 시작 주소이다. - 배열의 주소접근 예제) 위 그림에서 int형 변수 3개인 배열을 생성하였다. 첫번째 결과값의 배열의 첫번째 인덱스 array[0]의 주소(&)와 같은 주소를 갖는것을 확인 할 수 있다. sizeof 함수를 사용하여 바이트 크기를 측정하면, 64bit인 경우 주소의 크기는 8바이트를 갖는것을 볼 수 있으나 (32bit인 경우 4바이트) sizeof(array) 2016. 9. 9.
포인터(Pointer) □ 포인터는 변수의 메모리 주소를 저장하는 변수다 변수는 메모리 상의 저장 공간이므로 그 위치(주소)를 알면 사용할 수 있다. □ 주소 연산자(&)프로그램이 사용하는 메모리에는 바이트별로 주소값이 있다. 이 값은 0부터 시작하고 바이트 단위로 1씩 증가하므로 2바이트 이상의 크기를 갖는 변수는 여러 개의 주소값에 걸쳐 할당된다. 예를 들어 변수 a가 메모리 100번지부터 할당되었다면 100번지부터 103번지까지 4바이트에 걸쳐 할당된다. 주소는 변수가 할돵된 메모리 공간의 시작 주소를 사용 주소 연산자(&)의 사용법 예제 포인터는 주소를 저장하는 변수로 일반 변수와 마찬가지로 선언한 후에 사용한다. 선언하는 방법은 변수 앞에 *만 붙여주면 된다. 간접참조 연산자(*) 예제) *pa == num ① num.. 2016. 9. 8.
메모리(Memory)관리-(1) □ SMP(Symmetric Multiprocessing) - 복수 개의 CPU를 가지고 있는 컴퓨터 시스템 중 모든 CPU가 메모리와 입출력 버스 등을 공유하는 구조 □ NUMA(Non-Uniform Memory Access) - CPU들을 몇 개의 그룹으로 나누고 각각의 그룹에게 별도의 지역 메모리를 주는 구조 □ Bank - 리눅스에서 접근 속도가 같은 메모리의 집합 - UMA구조(NUMA의 반대)는 한 개의 뱅크가 존재 - NUMA구조라면 복수개의 뱅크가 존재 □ Node - 뱅크를 표현하는 구조 (~/include/linux/mmozone.h) - 만약 UMA 구조(Uniform Memory Access)의 시스템에서 리눅스가 수행된다면 한 개의 노드가 존재할 것이며, 이 노드는 리눅스의 전역 .. 2016. 9. 6.
getenv 함수 -linux system programming 쉘 프로그래밍 □ 형태 - 헤더 : #include char *getenv(const char * name); 반환(char *) 환경 변수의 값. 인수 : char * name 구하려는 환경 변수의 이름 getenv() 함수는 name 이름을 가지는 환경변수에 저장된 값을 읽어온다. 환경 변수는 "key=value" 형태로 저장되며, getenv()의 아규먼트로 들어가는 name은 Key 이름이 된다. 만약 일치하는 name을 가지는 환경변수가 있다면 "값"을 되돌려주고 없다면 NULL을 반환. 2016. 9. 4.
쉘(Shell) 프로그램 이 쉘의 main 함수에서는 사용자로부터 입력 받아서 run() 함수를 수행한다. 이때 사용자로부터 입력된 내용을 함수의 인자로 넘겨주는데, run() 함수는 이 입력 내용을 분석한다. 간단히 공백을 토큰으로 분리하는데, tokenize() 함수가 이 역할을 수행한다. 여러 개의 토큰으로 분리가 되면 첫 번째 토큰 값을 기준으로 내장 명령어인지 확인. 만약 쉘의 내장 명령어라면 해당 명령어를 수행, else 해당 프로그램의 수행을 시도. run함수에서 fork 함수를 통해 자식 프로세스가 생성되면 자식 프로세스는 exec 함수로 사용자가 입력한 프로그램을 수행시킨다. 프로세스의 인자를 배열로 넘겨 환경변수의 값으로 변환하여 프로세스의 실행이 가능하도록 execvp()함수를 이용함. 2016. 9. 4.
태스크(task)관리-(5) □ 문맥 교환(context switch) - 수행 중이던 태스크의 동작을 멈추고 다른 태스크로 전환하는 과정을 문맥 교환이라 부른다. 리눅스 커널은 태스크가 문맥교환 되는 시점에 어디까지 수행했는지, 현재 CPU의 레지스터 값은 얼마인지 등을 저장해 둔다. 이를 문맥 저장(context save)이라 한다. 즉, 스케줄링이 일어나면 문맥 교환이 발생하고, 문맥 교환 시엔 현재 수행 중이던 태스크의 문맥을 저장해 두어야 한다. □ 문맥 저장(context save) - 태스크가 문맥 교환 시점에 어디까지 수행되었는지를 현재 CPU의 레지스터값이 얼마인지를 저장한다. - task_struct의 thread 필드(struct thread_struct 타입)에 저장 - 태스크가 실행하다가 중단되어야 할 때 태.. 2016. 9. 2.
태스크(task)관리-(4) □ 런 큐와 스케줄링 - 여러 개의 태스크들 중에서 다음번 수행시킬 태스크를 선택하여 CPU라는 자원을 할당하는 과정을 스케줄링이라 한다. 리눅스의 태스크는 실시간 태스크0~99단계(숫자가 높을수록 우선순위가 높음), 일반 태스크100~139까지 사용하며, 실시간 태스크는 항상 일반 태스크 보다 우선하여 실행된다. ○ 런 큐와 태스크 - 리눅스에선 스케줄링 작업을위해 런 큐(Runqueue) 자료구조를 통해 관리한다. 스케줄러가 수행되면 해당 CPU의 런 큐에서 다음번 수행시킬 태스크를 골라낸다. 어떤 태스크를 선택할지는 일반 태스크를 위해 CFS(Completely Fair Scheduler)를 사용하며, 실시간 태스크를 위해서는 FIFO, RR, DEADLINE 정책을 제공한다. ○ 실시간 태스크 스.. 2016. 9. 2.
태스크(task)관리-(3) □ 상태 전이(State Transition)와 실행 수준 변화 태스크는 생성된 뒤, 자신에게 주어진 일을 수행하며, 이를 위해 디스크 I/O나 락(Lock)등 CPU 이외의 자원을 요청하기도 한다. 만약 태스크가 당장 제공해 줄 수 없는 자원을 요청한다면 커널은 이 태스크를 잠시 '대기' 하도록 만든 뒤 다른 태스크를 먼저 수행시키며, 태스크가 요청했던 자원이 사용 가능해지면 다시 '수행' 시켜 줌으로써 보다 높은 시스템 활용률을 제공하려 한다. 따라서, 태스크는 상태 전이(state transition)라는 특징을 가지게 된다. 그림에서 EXIT_ZOMBIE와 EXIT_DEAD는 task_struct 구조체의 exit_state 필드에 저장되는 값이며, 그 외의 상태들은 state 필드에 저장된다. .. 2016. 9. 1.
리눅스 커널 운영체제란? - 자원 관리자(resource manager) 자원(resource)이란? 운영체제가 관리해야 할 자원은 크게 - 물리적 자원 : CPU, 메모리, 디스크, 터미널, 네트워크 등 시스템을 구성하고 있는 요소들과 주변 장치 - 추상적 자원 : CPU를 추상화시킨 태스크(task), 메모리를 추상화시킨 세그먼트와 페이지, 디스크를 추상화시킨 파일, 네트워크를 추상화 시킨 통신 프로토콜, 패킷 등이 있다. - 물리적인 자원에 대응되지 않으면서 추상적인 객체로만 존재하는 자원 : 보안(security), 사용자 ID에 따른 접근제어(access control)등 cpu라는 물리적인 자원을 태스크라는 추상적인 자원으로써 제공해주는 태스크 관리자가 존재하며, 메모리를 세그먼트나 페이지라는 개념으로 제.. 2016. 8. 31.
태스크(task)관리-(2) fork()는 프로세스를 생성하는 함수이고, clone()은 쓰레드를 생성하는 함수인데 커널 내부에서 마지막으로 호출되는 함수 do_fork()로써 동일한데 이런게 가능한 이유는 리눅스는 모두 task를 생성하기 때문이다. fork()는 비교적 부모태스크와 덜 공유하는 task이고 clone()은 비교적 부모태스크와 많이 공유하는 task이다. 즉, do_fork()를 호출할 때 이 함수의 인자로 부모 태스크와 얼마나 공유할지를 정해 줌으로써, fork()와 clone() 함수 둘 다를 지원 할 수 있는 것이다. □ tgid(Thread Group ID) 시스템에 존재하는 모든 태스크는 유일하게 구분이 가능해야 한다. 태스크 별로 유일한 이 값은 task_struct 구조체 내의 pid 필드에 담겨있다... 2016. 8. 30.
fork()와 vfork()에 대해서. vfork() 함수는 fork()의 단점인 오버헤드(ex: 프로세스 구조체를 할당받는 시간과 메모리)를 낮춤으로써 고안되었다. vfork()가 도입됐지만 fork()함수 또한 상당히 개선되었다. 가장 주목할만한 점은, 'copy-onwrite'의 도입이다.프로세스의 주소공간의 복사는 ,같은 물리메모리들이 수정될때까지넌지시 허용되어왔다. 이것은 대략 , vfork()가 생기게된 원인에대해는 정당화되지 않는셈이다. 이것은 실제로 vfork()의 기능적인 면에서 시스템의 중요한 부분의 의미론적인 오류이다. 비록 호환성을 위해 아직 까지 vfork()가 존재하는것일지 모르지만, vfork()의 의미에 상관없이 fork()를 사용한다. 결국 fork()와 vfork()를 차이점에대해 어떨때 사용하는것에대해는 의미.. 2016. 8. 29.
프로세스와 쓰레드의 생성과 수행(부제 : 쓰레드와 프로세스의 차이점) 프로세스 생성 예제 이 예제는 전역변수 g와 지역변수 l을 가지고 있으며 fork()함수를 통해 새로운 프로세스를 생성한다. 그 결과, 16196번 pid를 가지는 부모 프로세스가 16197번 pid를 가지는 자식 프로세스를 생성하였음을 알 수 있다. 또한 이 프로그램에서는 자식 프로세스가 전역 변수와 지역 변수를 각각 1씩 증가시키고 있음을 알 수 있다. 반면, 부모 프로세스에서 g와 l변수 값을 출력하면 각각 원래 값인 2와 3이 출력됨을 알 수 있다. 이를 통해, 프로세스가 생성되면 주소공간을 포함하여 이 프로세스를 위한 모든 자원들이 새로이 할당됨을 알 수 있다. 따라서 자식 프로세스의 연산 결과는 자식 프로세스 주소 공간의 변수에만 향을 줄 뿐 프로세스 주소공간의 변수에는 영향이 없으며, 결국 .. 2016. 8. 29.
태스크(task)관리-(1) 태스크(task) : 자원소유권의 단위 프로세스(process): 동작중인 프로그램(running or runnable program)※ 리눅스는 각 프로세스에게 총 4 GB의 공간을 할당. (0 GB ~ 3 GB 유저공간, 3 GB ~ 4 GB 커널공간) 32bit-cpu 64bit-cpu에서는 2의 64승(16 EB) 크기의 가상 공간중 반은 유저공간, 반은 커널공간, 쓰레드 : 수행의 단위 프로그램(program) : 디스크에 저장되어 있는 실행 가능한 형태의 파일. ※ 실행 가능한 형태의 파일은 컴파일 과정을 거쳐 얻어진 바이너리 기게명렁어와 수행에 필요한 자료들의 집합으로 구성. 프로세스는 동작중인 프로그램이며, 커널로부터 할당받은 자신만의 자원을 가지고,cpu가 기계어 명령들을 실행함에 따라 .. 2016. 8. 29.
728x90