약간의 Make
explicit rule과 implicit rule의 경함
항상 explicit rule이 impicit rule에 우선한다.
make 함수
문자열 함수 | 텍스트를 조작 (치환, 분할, 결합 등) |
파일 이름 함수 | 경로, 확장자 등 파일 이름 처리 |
조건 함수 | 조건에 따라 값 선택 |
반복 및 리스트 함수 | 반복문, 리스트 처리 |
부가 기능 함수 | 셸 명령 실행, 오류 발생 등 |
subst
- 용도: 문자열 내에서 서브스트링(substring)을 치환합니다.
- 형식: $(subst 찾을문자열, 바꿀문자열, 대상문자열)
patsubst
- 용도: 패턴 매칭에 기반하여 치환합니다.
- 형식: $(patsubst 패턴, 대체문자열, 대상문자열)
strip
- 용도: 문자열 양쪽 끝의 공백을 제거합니다.
- 형식: $(strip 문자열)
파일 이름 처리 함수 (Filename Functions)
dir
- 용도: 파일 경로 중 디렉터리 부분만 반환합니다.
- 형식:$(dir 파일경로)
notdir
- 용도: 파일 경로 중 파일명 부분만 반환합니다.
- 형식: $(notdir 파일경로)
basename
- 용도: 파일 확장자 없이 이름만 반환합니다.
- 형식:$(basename 파일이름)
suffix
- 용도: 파일 확장자만 반환합니다.
- 형식:$(suffix 파일이름)
조건 함수 (Conditional Functions)
if
- 용도: 조건에 따라 다른 값을 반환합니다.
- 형식:$(if 조건, 참일때, 거짓일때)
or
- 용도: 여러 인자 중 첫 번째 비어있지 않은 값을 반환합니다.
- 형식:$(or 값1, 값2, 값3, ...)
and
- 용도: 모든 인자가 비어있지 않을 때 마지막 값을 반환합니다.
- 형식:$(and 값1, 값2, 값3, ...)
반복 및 리스트 함수 (Iteration and List Functions)
foreach
- 용도: 리스트에 대해 반복하여 작업을 수행합니다.
- 형식:$(foreach 변수, 리스트, 식)
word
- 용도: 리스트에서 특정 위치의 단어를 반환합니다.
- 형식:$(word 인덱스, 리스트)
words
- 용도: 리스트에 포함된 단어 수를 반환합니다.
- 형식:$(words 리스트)
wordlist
- 용도: 리스트에서 특정 범위의 단어들을 추출합니다.
- 형식:$(wordlist 시작, 끝, 리스트)
부가 기능 함수 (Other Utility Functions)
shell
- 용도: 쉘 명령어를 실행하고 결과를 반환합니다.
- 형식:$(shell 명령어)
error
- 용도: Makefile 실행 중 오류를 발생시키고 메시지를 출력합니다.
- 형식:$(error 오류메시지)
warning
- 용도: 경고 메시지를 출력하지만 빌드를 중단하지는 않습니다.
- 형식: $(warning 경고메시지)
라이브러리 제작(lib + name으로 명명)
static : 정적 라이브러리
lib.a(a = archive = 저장소(a.o, b.o ....))
ar : create, modify, and extract from archives
사용법 : ar [옵션들] lib이름.a 오브젝트파일1.o 오브젝트파일2.o ...
r | 아카이브에 새 오브젝트 파일을 추가하거나 이미 존재하는 파일을 교체함 (replace) |
c | 아카이브가 존재하지 않더라도 경고 없이 생성 (create) |
s | 아카이브의 심볼 테이블(symbol table)을 생성 또는 업데이트함 (symbol index) |
t | 아카이브 내부 파일 목록을 출력함 (table) |
x | 아카이브에서 오브젝트 파일을 추출함 (extract) |
d | 아카이브에서 오브젝트 파일을 삭제함 (delete) |
f | (force) 아카이브 파일 이름을 옵션 바로 뒤에 위치시킴 |
굳이 파일명과 위치를 작성할 필요 없이 -l(libname) -L(lib position, 현재 디렉토리 기준)
shared : 공유 라이브러리
프로그램 실행 시 외부에서 공유하여 로딩되는 라이브러리( .so (Linux), .dll (Windows), .dylib (macOS) 확장자 ) => 실행할 때(메모리에 올릴 때) 라이브러리를 가지고 온다.
- 하나의 라이브러리를 여러 프로그램이 동시에 공유하여 사용 가능 (메모리 절약)
- 실행 파일에는 함수의 참조 정보만 포함되고 실제 코드는 .so에 존재
- 라이브러리 버전 업 시 별도 재컴파일 없이 적용 가능
- 실행 시 .so 파일이 시스템 경로에 존재해야 함 (LD_LIBRARY_PATH 등 설정 필요)
gcc -fPIC -c foo.c # PIC 오브젝트 파일 생성, fPIC 위치가 정해지지 않은 코드
gcc -shared -o libfoo.so foo.o # 공유 라이브러리 생성
gcc main.c -L. -lfoo # 링크 시 사용
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./main # 실행 시 공유 라이브러리 로딩
#shared lib
CFLAGS = -fPIC
OBJS = mylib.o
TARGET = libmylib.so
all : $(TARGET)
libmylib.so : $(OBJS)
$(CC) -shared -Wl,-soname,$@ -o $@.1 $^ #######
ln -s $(TARGET).1 $(TARGET)
libmylib.a : $(OBJS)
$(AR) rcv $@ $^
ranlib $@
libpath:
@echo export LD_LIBRARY_PATH=`pwd`
clean :
@$(RM) -r $(OBJS) libmylib.* core
_________________________________________________________
#main file
LIBS = -lmylib
LIBP = -Llib
OBJS = main.o
TARGET = calc
all : $(TARGET)
$(TARGET) : $(OBJS)
## $(MAKE) -C lib
$(CC) -o $@ $^ $(LIBP) $(LIBS)
path:
@echo export LD_LIBRARY_PATH=./lib
clean :
## @make -C lib clean --no-print-directory
@$(RM) -r $(OBJS) $(TARGET)
dynamic : 동적 라이브러리
공유 라이브러리의 일종이지만, 프로그램이 실행 중에 필요할 때 직접 로딩하는 방식
dlopen(), dlsym() 함수 등을 사용하여 런타임에 .so를 로드하고 함수 포인터로 접근
공유 라이브러리와 다르게 메모리에 올릴 때 일괄적으로 가져오는 것이 아니라 사용자가 정할 수 있다.
- 프로그램 시작 시가 아닌, 실행 도중에 라이브러리를 로드
- 플러그인 시스템 등에 활용됨 (동적으로 기능 확장 가능)
- 코드 유연성과 확장성이 높음
- 런타임 에러 위험 있음 (예: 심볼 찾기 실패)
#include <dlfcn.h>
void* handle = dlopen("./libfoo.so", RTLD_LAZY);
void (*func)() = dlsym(handle, "foo_function");
func(); // 함수 실행
dlclose(handle);
GDB
core dump : fault 발생 시 당시 스택, 레지스터 값 등을 파일로 저장, 그 당시의 상황을 재현하는 것이 디버깅에 있어서 매우 중요
시작과 종료
gdb [프로그램명] : 시작
q(quit) or ctrl+d : 종료
소스보기(list)
브레이크 포인트
b func : func 함수의 시작부분에 브레이크 포인트 설정
b 10 : 10행에 브레이크 포인트 설정
b *0x8049000 : 특정 주소에 브레이크 포인트 설정
tb : b와 같으나 1회용 브레이크 포인트. 문법은 b와 동일
info b : 현재 브레이크 포인트 보기
cl : 브레이크 포인트 지우기
d : 모든 브레이크 포인트 지우기
진행 명령어
r(run) : 프로그램 수행
k(kill) : 프로그램 수행 종료
s(step) : 현재 행 수행 후 정지, 함수 호출시 함수 안으로 들어감
s 5 : s 다섯번 수행
n(next) : 현재 행 수행 후 정지, 함수 호출시 함수 수행 다음 행으로 감
n 5 : n 다섯번 수행
c(continue) : 다음 브레이크 포인트까지 진행
u : 현재 루프를 빠져나감
finish : 현재 함수를 수행하고 빠져 나감
return : 현재 함수를 수행하지 않고 빠져 나감
return : 위와 같으나 리턴값 지정
와치 포인트
watch [변수명] : 특정변수에 와치 포인트를 설정하고, 특정변수가 바뀔 때마다 브레이크가 걸리면서 이전/현재 값을 출력한다.
변수출력 관련
info locals : 현재 스택의 로컬변수 모두를 출력
info variables : 전역변수 모두 출력 (스압)
p [변수명] : 해당변수 value 출력
포인터변수 입력시 주소값 출력, *포인터변수명 -> 실제 value 출력
p $[레지스터명] : 레지스터값 출력
p *[포인터] : struct/class의 배열일 때 배열의 크기를 알림
p /[출력형식][변수명] : 출력형식에 맞추어 변수값 출력
t : 2진수
o : 8진수
d : 부호없는 10진수
u : 부호없는 10진수
x : 16진수
c : 최초 1바이트 값을 문자형으로 출력
f : 부동소수점
a : 가장 가까운 심볼의 오프셋 출력
p (캐스팅)[변수명] : 변수를 캐스팅하여 출력 ( p (char*)ptr )
p [포인터변수or배열]+[숫자] : 특정 주소 + 숫자 위치 출력 ( p (array[1]+4) )
p [변수명] = [value] : 특정 변수의 값을 설정
info registers : 레지스터 전체 출력
display [변수명] : 매번 p 치기 귀찮으니 특정변수 진행 중 계속 출력
p와 동일한 방식으로 출력형식 지정가능
disalbe display [번호] : 일시적으로 디스플레이 중단
enable display [번호] : 중단했던 번호 다시 출력
undisplay [번호] : 출력하던 display 변수 제거
스택 상태 검사
info f : 스택 프레임 내용 출력
info args : 함수 호출시 인자를 출력
info locals : 함수의 지역변수를 출력
info catch : 함수의 예외 핸들러를 출력
bt : 전체 스택 프레임 출력(콜스택)
frame [스택번호] : 스택번호의 스택 프레임으로 이동
up : 상위 스택 프레임으로 이동
up [숫자] : 숫자만큼 상위 스택프레임으로 이동
down : 하위 스택 프레임으로 이동
down [숫자] : 숫자만큼 하위 스택프레임으로 이동
메모리 상태 검사
x/[범위][출력형식][범위의단위] [메모리주소나 함수명]
범위 : 기본 4바이트 단위
출력 형식
t : 2진수
o : 8진수
d : 부호없는 10진수
u : 부호없는 10진수
x : 16진수
c : 최초 1바이트 값을 문자형으로 출력
f : 부동소수점
a : 가장 가까운 심볼의 오프셋 출력
s: 문자열로 출력
i : 어셈블리 형식으로 출력
범위의 단위
b : 1 byte
h : 2 byte
w : 4 byte
g : 8 byte
ex) x/10 main : main 함수로부터 40 byte 출력
기타
disas [함수명] : 특정함수의 어셈블리 코드 출력
disas [주소] [주소] : 주소 사이의 어셈블리 코드 출력
call [함수명(인자)] : 특정 함수를 인자값으로 호출
jump *[주소] : 주소로 강제적으로 분기
jump [행번호] : 특정 행으로 강제 분기
jump [함수명] : 특정 함수로 강제 분기
info signals : signal 종류 출력
info tab키 : info로 확인 가능한 명령어 출력
set {타입}[주소] = [값] : 특정 메모리에 값을 지정 ( set {int}0x8048300 = 100 )
출처 : https://mitny.github.io/articles/2016-08/gdb-command
Posts | MitNy.log
기록 저장소
mitny.github.io
'VEDA 복습' 카테고리의 다른 글
VEDA 교과평가2 준비(리눅스, Make, CMake, Git etc) (0) | 2025.05.01 |
---|---|
VEDA 33일차 - GDB, CMake, Git, Docker (1) | 2025.04.30 |
VEDA 31일차 - Makefile (2) | 2025.04.28 |
VEDA 29일-30일차 - 임베디드 리눅스 프로그래밍 (0) | 2025.04.25 |
VEDA 28일차 - 임베디드 리눅스 (1) | 2025.04.23 |