Download presentation
Presentation is loading. Please wait.
1
Chapter 13 Programming Tools
2
Contents C compiler Debugging tool System call Make utility
lint, dbx System call Make utility Source code management SCCS 이 장에서는 C 프로그래밍을 위한 도구를 소개하고 있습니다. 배울 내용은 C compiler(cc)의 사용법. 디버깅 툴인 lint와 dbx 시스템콜의 소개 make 유틸리티의 사용법 소스코드 관리 소프트웨어인 SCCS 입니다.
3
C 프로그램의 컴파일(1) $ cc tabs.c -c : object file 생성 -o : output file 생성
-g : debugging 정보 첨가 $ cc calc.c -lm ; math library $ cc -O ledger.c acctspay.c acctsrec.c ; optimizer $ a.out < mymemo ; call a.out $ mv a.out tabs ; save a.out file 컴파일 과정은 4단계입니다. preprocessor --> compiler --> assembler --> link editor cc는 4단계를 차례로 실행해 줍니다. 즉, preprocessor와 assembler, link editor를 자동으로 호출합니다. 또한 파일이름을 보고 알아서 해당 단계를 인식합니다. 즉, .c 파일은 preprocessor와 compiler을, .s 파일은 assembler를 .o 파일은 link editor를 호출합니다. 보통, preprocesseor - cpp assembler - as link editor - ld 를 사용합니다.
4
C 프로그램의 컴파일(2) 실행 파일의 지정 $ cc -o accounting ledger.c acctspay.c acctsrec.c $ accounting 목적 파일의 생성 $ cc -c ledger.c acctspay.c acctsrec.c $ ls acctspay.c acctsrec.c ledger.c acctspay.o acctsrec.o ledger.o 설명이 필요 없지만, -o 다음에는 실행파일의 이름이 오고요. -c 는 오브젝트 파일만 생성하지요.
5
C 프로그램 디버깅 도구(1) lint Symbolic Debuggers 프로그램 에러 및 문제점의 발견. 예를 들어
변수의 값이 지정되기 전에 사용된 경우. 정의는 되었으나 사용되지 않은 인자. 리턴되지 않은 리턴값을 사용하는 function의 발견. Symbolic Debuggers 종류: adb, sdb, dbx, gdb 프로그램 수행을 감시 및 제어하는 기능 포함. 프로그램 수행 단계를 추적하며 변수의 값을 조사. 에러 발생시의 프로그램 상태 분석 (core파일 이용). 디버거를 사용하기 위해 컴파일시 -g 옵션을 사용. % cc -g tabs.c -o tabs lint filename.c - 에러의 가능성이 있는 부분을 발견해 줌. 리턴되지 않은 리턴값을 사용하는 function의 발견???? 이런 경우가 가능합니다. function() { return; } d = function();
6
C 프로그램 디버깅 도구(2) dbx 명령어 list 현재 위치에서 처음 10줄을 보여 줌.
where 수행중인 function의 이름과 주소를 제시. whatis 특정 변수에 대한 선언문 제시. whereis 변수의 위치 제시. stop 수행중인 프로세스를 중단. run 현재 프로그램의 실행. next, step 다음 명령어 수행 print 변수의 값을 검사. cont 계속 수행하도록 지시. quit 디버거 세션의 종결. help 도움말. 명령어의 요약. gdb 와 유사한 명령어를 가지고 있습니다. 요즘은 주로 gdb나 xxgdb를 사용하죠. 하지만 명령어가 비슷하니 배워 두면 gdb를 사용할 수 있겠죠. list - 현재 디버깅 위치에서 처음 10줄을 보여 줍니다. list 2,30 - 2~30번째 줄을 보여 줍니다. whereis - 현재 수행중인 함수의 이름 whatis 변수이름 - 현재 스코프에서의 변수의 선언문을 보여 줌 whereis 변수이름 - 프로그램 전체에서 이 이름을 갖는 변수가 쓰이는 곳. stop - gdb의 break 명령과 유사. 다음과 같이 사용 stop in 함수이름 stop if 조건 stop at 리인번호 run - 프로그램의 수행 시작 next - 한 줄 수행. step - 한 줄 수행하되 그 줄에 함수가 있으면 함수 안으로 들어감. print 변수 - 변수의 값을 출력 cont - stop된 프로그램의 재수행
7
System Calls(1) 유닉스 커널의 기본적 기능
프로세스의 제어 파일시스템 관리 주변장치의 구동. 시스템 호출 (system calls)은 라이브러리 루틴의 호출과는 달리 사용자 프로그램에서 "직접" 운영체제의 커널로 하여금 어떤 작업을 수행하도록 지시. 보통 한 개의 라이브러리 루틴의 수행을 위해 여러 개의 시스템 호출을 필요로 함. 예를 들어, fprintf(), putchar(), getchar() 등은 라이브러리 루틴이고, 이 루틴들은 write(), read()등의 시스템 콜을 사용합니다 보통, 시스템 호출은 사용하기 불편하기 때문에, 프로그래머가 사용하기 편하게 라이브러리 루틴이 제공됩니다.
8
System Calls(2) 프로세스 제어를 위한 시스템 호출 파일 시스템의 접근을 위한 시스템 호출
wait(), exit(), nice(), kill() 파일 시스템의 접근을 위한 시스템 호출 stat(), access(), creat(), open(), read(), write(), close(), unlink(), chmod(), chown() 주변장치의 접근을 위한 시스템 호출 보통의 파일을 접근하기 위한 방법과 같은 방법을 사용 하여, /dev 디렉토리에 있는 파일에 읽고 쓰는 명령을 수행함으로써 가능. 프로세스 제어를 위한 기본적인 시스템 호출은 fork()오 exec()이 있습니다. 이미 앞에서 설명을 했었죠. wait() - 자식 프로세스가 종료하기를 기다림. exit() - 현재 프로세스를 종료 nice() - 현재 프로세스의 우선순위(Priority)를 낮춤. kill() - 다른 프로세스에게 시그널을 보냄 사용자의 편의를 위해 파일 시스템을 접근하는 시스템 호출이 제공됨. stat() - 파일의 상태(status) 정보를 제공. 파일크기, inode 번호, owner와 group에 관한 정보 등. access() - 파일에의 접근권한을 체크함. unlink() - link를 없앰.즉, 파일의 삭제. remove()는 라이브러리 루틴. 주변 장치(프린터, 화면 등)를 접근하기 위해서는, 단지 해당 파일(/dev/….)를 오픈하여 read(), write()를 수행하면 됨. 구체적인 작동은 kernel device driver가 해 줍니다. 유닉스의 큰 장점이죠.
9
Make 유틸리티(1) 한 개의 프로그램이 여러 개의 원시 파일과 헤더 파일을 가진 경우, 하나의 파일을 변경하면 이에 종속된 관계에 있는 다른 모든 파일들이 다시 컴파일되어야 한다. make 유틸리티는 재컴파일하는 과정을 자동화. makefile의 양식 target: prerequisite-list # target/dependency line <TAB> construction-commands # command line target이 prerequisite-list에 dependent합니다. target의 변경시간보다 prerequisite-list의 변경시간이 더 최근이면 그 아래의 command line을 수행합니다. command line의 수행은 Bourne shell이 해 주므로 Bourne shell이 할 수 있는 명령은 모두 가능합니다. 뒤에 makefile의 예가 나옵니다.
10
Make 유틸리티(2) touch Macros Built-in Macro
특정 파일의 변경 시간을 변화시킨다. 모든 파일이 up to date 일 때, 특정 파일을 touch 후 make를 실행하면, 이에 종속된 파일들이 모두 다시 컴파일됨. Macros makefile안에서 매크로를 생성하고 사용할 수 있다. Built-in Macro CC : c compiler를 지정하는 macro : 현재 target의 이름 $* : 현재 target에서 확장자를 제외한 이름 매크로의 예는 뒤에 자세히 나옵니다. Built-in Macro를 사용해서 컴파일러를 선택할 수 있습니다. assembler : AS c : CC c++ : CCC fortran : FC link editor : LD
11
Makefile의 예 num.h tab.h form.h size.c length.c size.o length.o form
form: size.o length.o cc -o form size.o length.o size.o size.c form.h cc -c size.c length.o: length.c form.h cc -c length.c form.h: num.h table.h cat num.h table.h > form.h num.h tab.h form.h size.c length.c size.o length.o makefile의 dependency관계가 오른쪽의 dependency graph처럼 된다는 것을 설명하면 되겠죠. form
12
Macro 사용 예 CFLAGS = -O FILES = in.c out.c ratio.c process.c tally.c
OBJECTS = in.o out.o ratio.o process.o tally.o HEADERS = names.h copanies.h conventions.h report: $(OBJECTS) cc -o report $(OBJECTS) ratio.o: $(HEADERS) process.o: $(HEADERS) tally.o: $(HEADERS) print: pr $(FILES) $(HEADERS) | lp makefile의 일부입니다. 매크로를 사용할 때는 $(..)라고 사용합니다. ration.o, process.o, tally.o에는 construct command-line이 없습니다. target을 만드는 명령이 없으면, make는 이런 경우에 알아서 cc -c ratio.c를 수행합니다. 이것을 암시적 의존관계(implied dependency)라고 하는데, make가 인식할 수 있는 몇 가지 programming language에 대해 제공됩니다. make는 ratio.o를 만들기 위해서 ratio.c(C)나 ratio.f(FORTRAN), ratio.s(ASSEMBLY), ratio.p(PASCAL)등의 소스코드를 찾아서 컴파일해 줍니다. 또한, 포트란은 보통 f77, 어셈블러는 as, 파스칼은 pc를 호출합니다.
13
Source Code Management
대규모의 소프트웨어를 여러 사람이 장기간에 걸쳐 개발할 때에, source code와 document의 버전 관리를 위한 시스템 source file의 개발과정을 추적하고, 하나의 파일이 동시에 여러 사람에 의해서 변경되는 것을 방지 Source Code Control System (SCCS) Revision Control System (RCS) 이 부분은 안 중요하니깐(?) 실습은 생략하고 이런게 이렇다는 것만 설명합시다. 특히, SCCS와 RCS 중에서 SCCS만 하도록 합니다. sccs 명령어가 교재에 있는 예와 약간 다릅니다.
14
SCCS(1) delta : a set of changes to a source code version number
release.level.branch.sequence-number initially 1.1 branch delta가 더 해질 때마다(소스코드에 변경이 있을 때마다) 버전이 올라갑니다. 버전번호는 2개 또는 4개의 숫자로 이루어 집니다. 초기에는 1.1입니다. level과 sequence-number는 소스코드가 변경될 때마다 자동으로 증가합니다. release와 branch는 사용자의 명령으로 변경됩니다. 변경방법은 뒤에 나옵니다. 또는 예전 버전을 변경하면 branch가 자동으로 됩니다.(예를 들어, 2.2까지 개발한 후에 2.1을 다시 고치면 로 branch가 됩니다.) 위의 그림에서, 처음 파일을 생성하면 1.1이라는 버전을 갖습니다. 이 후에 2번의 수정이 있어서 1.2, 1.3으로 버전이 올라갔습니다. 소스코드에 큰 변경이 있으면 사용자는 release를 높일 것입니다. 그러면 2.1로 버전이 바뀝니다. 만약 소스코드가 두 방향으로 개발된다면 branch를 합니다. 그러면 은 branch한 소스코드가 되고, 이후로는 , 으로 버전이 붙여집니다. 남은 2.1를 계속 변경하면 2.2, 2.3..이 되겠죠. 1.1 1.2 1.3 2.1 2.2
15
SCCS(2) Putting files under SCCS control Making an SCCS directory
$ mkdir SCCS Creating an SCCS file $ sccs create filename filename is moved to ,filename a history file s.filename is created in SCCS 먼저 SCCS라는 디렉토리를 만듭니다. sccs create test.c 라고 하면(test.c는 미리 만들어져 있어야 합니다.), test.c 는 ,test.c로 변경됩니다.(첫 글자가 comma입니다.) 이후의 변경사항은 SCCS/s.test.c라는 파일에 모두 저장됩니다. 즉 원본파일인 ,test.c는 그대로 남습니다. 이후로 사용자가 어떤 파일을 요구하면 원본파일(,test.c)에다가 변경된 사항(s.test.c에 저장되어 있는)을 적용해 줍니다.
16
SCCS(3) Checking out files for reading for editing early version
$ sccs get filename // 특정 파일 $ sccs get SCCS // SCCS의 모든 파일 파일이 현재 디렉토리로 복사됨 for editing $ sccs get -e filename $ sccs get -e SCCS early version $ sccs get -r version-number cancelling an editing session $ sccs unedit filename check-out은 파일을 꺼내 오는 것이고, check-in은 변경한 파일을 다시 넣는 것입니다. reading이나 editing을 위해서 파일을 꺼내 오면 사용자의 현재 디렉토리에 원본파일에 변경된 사항을 적용한 파일을 복사해 줍니다. 즉, sccs get -e test.c 라고 하면 현재 디렉토리에 test.c라는 파일이 생성됩니다. 이후로는 vi등과 같은 에디터로 작업을 합니다. 예전 버전을 고치고자 하면, sccs get -e -r1.1test.c라고 하면 됩니다. 이런 경우에 check-in을 하게 되면 자동으로 branch가 되어 의 버전을 갖습니다.
17
SCCS(4) Checking in files $ sccs delta filename check-in 한 사용자인지를 확인
comment 요구 변경된 내용을 저장 현재 디렉토리의 복사본 삭제 sccs get -e filename으로 현재 edit 중인 파일은 sccs delta filename으로 파일을 저장하기 전에는 edit할 수 없음 sccs delta test.c라고 하면 변경한 내용을 저장합니다.
18
SCCS(5) Getting information about files Whick files are being edited?
$ sccs info $ sccs info -u username What is the lastest versions of the each file? $ sccs what filenames What is the history of this fils? $ sccs prt filename
19
SCCS(6) Creating new releases Creating new branch
$ sccs get -e -r2 tmp.c 1.3 new delta 2.1 7 lines Creating new branch $ sccs get -e -r1.3 filename new delta 7lines
Similar presentations