static 함수 사용이유
프로그램 내에서 중복되는 이름의 함수가 있을 수 있기 때문에 사용
static함수로 만들게 되면 .c 파일 내에서만 사용이 가능한 함수가 되기 때문에 이름 중복과 관련된 오류가 발생하지 않는다.
- void 형 함수에서도 return; 을 쓸 수 있다.
아무것도 반환하지 않는 return; 즉, 단지 함수를 종료시키기 위한 return;의 의미로 사용
int atoi(const char *str); //문자열을 정수 타입으로
double atof(const char *str); //문자열을 실수 타입으로
long atol(const char *str); //문자열을 long 정수 타입으로
//atoi("문자만"); 0
//atoi("숫자만"); 2021
//atoi("숫자+문자"); 2021
//atoi("문자+숫자"); 0
return: 성공시 해당 정숫값, 실패/str에 정수가 포함되어있지 않은 경우 0
//문자열을 long 값으로 변환 합니다. 2진수, 8진수, 16진수 값을 10진수로 변환 합니다. (string to long)
long strtol(const char *nptr, char **endptr, int base);
//nptr: NULL로 종결되는 수식을 포함하는 문자열의 포인터
//endptr: 변환이 멈춰진 문자열의 포인터
//base: 변환될 문자열의 기수(2, 8, 10, 16진수 선택) 2~36진수까지 가능
//return: 정수 값(long), 변환 실패시 0L 리턴. errno는 ERANGE로 설정
// -2,147,483,648 ~ 2,147,483,647
//문자열을 unsigned long 값으로 변환 합니다. (string to unsigned long)
unsigned long strtoul(const char *nptr, char **endptr, int base);
//nptr: NULL로 종결되는 수식을 포함하는 문자열의 포인터
//endptr: 변환이 멈춰진 문자열의 포인터
//base: 변환될 문자열의 기수(2, 8, 10, 16진수 선택) 2~36진수까지 가능
//return: 양의 정수 값(unsigned long), 변환 실패시 0L 리턴. errno는 ERANGE로 설정
// 0~4,294,967,295
//문자열을 double 값으로 변환 합니다. (string to double)
double strtod(const char *nptr, char **endptr);
//nptr: NULL로 종결되는 수식을 포함하는 문자열의 포인터
//endptr: 변환이 멈춰진 문자열의 포인터
//return: 실수 값(double), 변환 실패시 0.0 리턴. errno는 ERANGE로 설정
// 1.7E +/- 308 (15 digits)
long long int strtoll(string, &end, base);
int getopt(int argc, char *const argv[], const char *optdecl);
extern char *optarg;
extern int optind, opterr, optopt;
argc, argv[]: main()의 인자를 그대로 전달
optdecl: 옵션에 해당하는 문자들을 하나의 문자열로 묶어서 지정
1) 파라미터를 취하지 않는 옵션
-a -t -x는 'atx'로 지정(이 때 문자 나열 순서는 결과에 영향 미치지 않는다.)
2) 파라미터를 받는 옵션
해당 옵션 문자 다음에 :(콜론)을 붙인다. 앞의 세가지 옵션을 더하여 파라미터값 받는 옵션 -f가 있다면 'af:tx'해도 되고 'f:atx' 또는 'atxf:'해도된다.
- 전역 변수 'char *optarg'을 통해 파라미터 값을 얻을 수 있다.
이 외에도 몇가지 전역 변수- char * optarg: 현재 처리 중인 옵션 파라미터(문자 다음에 오는 인수), 파라미터가 없는 경우 0(NULL)
- int optind: 현재 처리 중인 옵션의 argv 인덱스
- int optopt: 알 수 없는 옵션을 만났을 때 해당 옵션이 여기에 들어간다.(리턴값: ?)
- int opterr: 에러 발생시 출력할지 말지를 정함(1(true)일때 출력)
//파라미터 값이 빠진채로 실행되었다면 이때는 옵션이 인식할 수 없는 옵션으로 처리된다. //그래서 optopt값으로 확인할 수 있다. if(optopt == 'w') printf("option -w requires FILENAME\n\n");
3) 파라미터로 -나 --를 넘겼을 때
- --를 만나면 -1반환하여 while문 벗어난다.
따라서 --는 getopt()에 의한 옵션 처리를 중지하고 프로그램에서 별도로 처리할 인자를 넘기고 싶을 때 사용- -를 만나면 옵션으로 인식하지 않고 다음 옵션으로 넘어감(주석처럼 무시)
GNU libc에는 --로 시작하는 옵션을 해석하는 getopt_long()이 준비되어있다.
#define _GNU_SOURCE
#include <getopt.h>
int getopt_long(int argc, char * const argv[],
const char * optdecl, //검색하려는 짧은 옵션들의 문자열
const struct option *longoptdecl, //롱옵션의 정의
int *longindex); //option에 해당되는 index 번호
//*longindex에는 구조체 배열 중 몇 번째 option의 값이 검출되었는지를 알려주기 위해서 이 값이 함수 내에서 업데이트
//롱옵션의 정의
struct option{
const char *name;//롱옵션의 이름: lines, help 등
int has_arg;
//no_argument(또는 0): 파라미터를 취하지 않음
//required_argument(또는 1): 반드시 파라미터를 취함
//optional_argument(또는 2): 파라미터를 취할 수도 있음
int *flags;
//옵션이 입력되었다면 지정한 값을 받을 수 있는 변수 주소입니다.
//NULL: getopt_long()은 val의 값을 반환
//NULL 이외: getopt_long()은 0을 반환하고 *flags에 val의 값을 대입
int val;
//옵션이 입력되었다면 여기에 지정한 값을 flag 변수에 대입
//flag의 값에 따라 지정한 곳에 반환할 값
};
extern char *optarg;
extern int optind, opterr, optopt;
getopt()의 모든 기능을 포함하며 --로 시작하는 긴 옵션의 파싱도 가능하다.
기본적 사용방법과 반환값이 같다.
옵션 배열은 {0,0,0,0} 센티넬에 의해 만료된다
구현 전략
- 짧은 옵션들을 먼저 정의한다.
- 긴 옵션명을 추가로 정의한다.
- 긴 옵션명 중에서 짧은 옵션명과 동일한 옵션인 것과 그렇지 않은 것을 구분한다.
- 짧은 옵션과 다른 긴 옵션의 경우 결과를 저장할 flag가 될 변수를 미리 준비한다.
- 1~4의 내용으로 옵션 구조체 배열을 정의한다. 이 배열은 {0, 0, 0, 0}의 센티넬로 마무리한다.
- getopt_long() 함수를 루프 속에서 처리한다.
- -1이 리턴될 때까지 반복한다
flags 멤버와 val 멤버는 함께 사용해야 하는데, 이 둘을 사용하는 방법에는 크게 두가지가 있다.
https://github.com/Jpub/Linux_for_Everyone/blob/master/head4.c
getopt_long_only() : '-', '--' 모두 긴 이름 옵션으로 검색
void *memcpy(void *dest, const void *source, size_t num);
dest: 복사받을 메모리를 가리키는 포인터
source: 복사할 메모리를 가리키고 있는 포인터
num: 복사할 데이터(값)의 길이(바이트 단위)
strcpy는 문자열 복사 함수로 길이지정을 안하는 대신 문자열이 반드시 \0로 끝나야합니다.(\0을 만나면 종료)
memcpy는 형에 관계없이 임의의 영역을 지정한 byte수만큼 복사(\0까지 처리하기 위해 size+1)
컴파일 시 -g 옵션을 주어야함
$ gcc -Wall -g -o head head.c
$ gdb <프로그램명>
$ gdb <프로그램명> <core파일명>
$ gdb <프로그램명> <실행중인 프로세스 pid>
break <함수이름>
break <라인번호>
break <파일이름:라인번호>
break <파일이름:함수이름>
break +<offset> // 현재 위치에서 오프셋 라인 뒤에 설정
break -<offset> // 현재 위치에서 오프셋 라인 뒤에 설정
break *address // 이미지의 주소 영역을 breakpoint로 설정
break <...> if <condition> // condition이 만족할때만 중단
info break
info b
i b
>>>
Num Type Disp Enb Address What
2 breakpoint keep y <PENDING> a
3 breakpoint keep y <PENDING> b
4 breakpoint keep y <PENDING> c
clear <설정된 함수이름>
clear <설정된 라인번호>
clear <설정된 파일이름:라인번호>
clear <설정된 파일이름:함수이름>
delete // 설정된 모든 브레이크포인트를 지운다.
delete <breakpoint 번호> //번호에 해당하는 중단점을 지운다.
delete <breakpoint 번호> <breakpoint 번호> // 번호에 해당하는 중단점 모두 지운다.
en // 모든 중단점 활성화
enable // 모든 중단점 활성화
enable <중단점 번호> // 해당 중단점 활성화
enable <중단점 번호> <중단점 번호> // 해당 중단점 모두 활성화
dis // 모든 중단점 활성화
disable // 모든 중단점 활성화
disable <중단점 번호> // 해당 중단점 비활성화
disable <중단점 번호> <중단점 번호> // 해당 중단점 모두 비활성화
- run // 프로세스를 새로 실행, 이미 실행중이라면 재시작
- continue // 다음 중단점까지 프로그램을 재개
- conitnue n // 프로그램을 재개, 중단점을 n번 건너뜀
- next // 실행중인 프로세스를 한줄 실행, 함수 실행시 내부로 진입 X
- next n // 실행중인 프로세스를 n줄 실행, 함수 실행시 내부로 진입 X
- step // 실행중인 프로세스를 한줄 실행한다. 함수 실행시 내부로 진입
- step n // 실행중인 프로세스를 n줄 실행한다. 함수 실행시 내부로 진입
- finish // 현재 함수를 수행하고 빠져나간후 리턴값을 출력한다.
backtrace : 현재 위치의 함수 call stack을 출력한다.
backtrace // 현재 실행 위치의 함수 call stack을 출력한다.
bt // 현재 실행 위치의 함수 call stack을 출력한다.
bt N // 현재 실행 위치의 함수 call stack 중 처음 N개 출력
bt -N // 현재 실행 위치의 함수 call stack 중 마지막 N개 출력
bt full // local 변수들도 함께 출력
print <val> // 변수 출력
p <val> // 변수 출력
p <func::val> // 해당 함수의 변수를 출력한다.
p *<ptr> // 포인터의 값
p <addr> // 주소에 있는 값
p arr[n] // arr 배열의 n번째 값 출력
p -pretty *<구조체> // 예쁘게 출력한다. 구조체를 출력할 때 용이하다.
p/x <val> // x(16진수) 형식으로 변수 출력
display expr // 매 실행시 마다 출력한다.
display/fmt expr // 매 실행시 마다 fmt 포멧 형식으로 출력한다.
info dis // 설정된 display를 출력한다.
info display // 설정된 display를 출력한다.
enbale display // 모든 display를 활성화 시킨다.
en dis // 모든 display를 활성화 시킨다.
en dis <번호> <번호> // 번호에 해당하는 display를 활성화 시킨다.
disbale display // 모든 display를 비활성화 시킨다.
dis dis // 모든 display를 비활성화 시킨다.
dis dis <번호> <번호> // 번호에 해당하는 display를 비활성화 시킨다.
return // 현재 함수를 수행하지 않고 빠져나간다.
return -1 // 현재 함수를 수행하지 않고 빠져나간다. 리턴값은 -1
list // 현재 위치의 소스 출력
list 100 // 100번째 라인 주변 소스 출력
list funtion // 지정 함수의 소스 출력
list - // 직전에 출력한 소스 출력
set listsize count // 출력하는 라인수를 count로 설정한다.
set listsize unlimited // 출력하는 라인수 무제한
$ ulimit -a
//core file size (blocks, -c) 0 이면 메모리 생성해야하므로
$ ulimit -c unlimited
$ file core
$ gdb tmsize core
//콜스택 backtrace
$ bt
//frame 선택해서 스택 정보 보기
$ f 3
//해당 스택의 소스보기
$ list
//해당 스택의 argument 보기
$ info arg
//해당 스택의 local value 보기
$ info local
위와 같은 방식으로 코어 덤프 파일로부터 콜스택을 추적하여 프로그램이 비정상 종료된 원인을 찾아낸다.