[Linux] GDB(GNU Debugger), gcc, gdb

pos++·2023년 11월 2일
0

Linux

목록 보기
4/16
post-thumbnail

2023.10.28 TIL

GDB 설치

sudo apt install gcc gdb

gcc compile

gcc -g -o main main.c-o 로 실행파일 이름을 main으로 지정

gdb execute

gdb main

종료

q control+D

소스 찾아가기 (list)

l → main 함수를 기점으로 소스의 내용 출력

l 27 → 27행 주변의 소스 출력

l func → func 함수의 소스 출력

l a.c:27 → a.c 파일의 func 함수의 소스 출력

l a.c:func → a.c 파일의 27행을 기준으로 출력

Breakpoint 사용하기

b func → func 함수에 breakpoint 설정

b 27 → 27행에 breakpoint 설정

b a.c:func → a.c 파일의 func 함수에 breakpoint 설정

b a.c:27 → a.c 파일의 27행에 breakpoint 설정

b +2 → 현재 line에서 2줄 이후 지점에 breakpoint 설정

b -2 → 현재 line에서 2줄 이전 지점에 breakpoint 설정

b *0x8049000 → 0x8049000 주소에 breakpoint 설정 (어셈블리로 debugging시 사용)

b 27 if var == 0 → 27행에 breakpoint 설정하되, var 변수값이 0일때 작동

Breakpoint 삭제하기 (clear)

cl func → func 함수에 breakpoint 지움

cl 27 → 27행에 breakpoint 지움

cl a.c:func → a.c 파일의 func 함수에 breakpoint 지움

cl a.c:27 → a.c 파일의 27행에 breakpoint 지움

cl → 모든 breakpoint 지움

프로그램 run, kill

r → 프로그램 실행 (재시작)

r arg1 arg2 → arg1과 arg2를 argument로 프로그램 실행

k → 프로그램 수행 종료

Backtrace

bt → 오류가 발생한 함수를 역으로 찾아감

변수 정보 보기

info locals → 현재 상태에서 지역변수들의 리스트 출력

info variables → 현재 상태에서 전역변수들의 리스트 출력

p lval → lval의 값 출력

p func → func 함수의 주소값 출력

p pt → pt가 구조체라면 구조체의 주소 출력

p *pt → pt가 구조체라면 구조체의 값 출력

p **pt → *pt가 구조체라면 구조체의 값 출력

info registers → register 값 전체를 한번에 확인

Debugging

s → 현재 출력된 행 수행하고 멈추지만, 함수의 경우 함수 내부로 들어가서 수행

s 4 → s를 4번 입력한것과 동일

n → 현재 행을 수행하고 멈추지만, 함수의 경우 함수를 수행하고 넘어감

n 4 → n을 4번 입력한것과 동일

c → 다음 breakpoint를 만날때까지 계속 수행

u → for문에서 빠져나와서 다음 breakpoint까지 수행



예제 0

이 프로그램에서 Segmentation fault가 만들어지는 이유

#include <stdio.h>

void main() {
	char *temp = "Paras";
	int i;
	i = 0;

	temp[0] = 'F';

	for(i  =0; i < 5; i++)
		printf("%c\n", temp[i]);
}

→ *temp는 컴파일러가 const로 지정하고 readonly 영역에 값을 할당하는데, temp[0]으로 값을 변경하려고 했기 때문

→ 해결 : char buf[100] 처럼 메모리를 잡는다



예제 1

a.txt를 복사하여 새로운 파일을 생성하는 mycp.c 프로그램 작성

./mycp a.txt result.txt 처럼 파일이름은 명령행 인자로 받는다

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#define BUFSIZE 512

int main(int argc, char** argv) {
	int source = open(argv[1], O_RDONLY);
	int result = open(argv[2], O_RDWR | O_CREAT, 0644);
	ssize_t nread;	

	if(source < 0){
	  fprintf(stderr,"open error\n");
    exit(1);
	}

	while((nread = read(source, buffer, BUFSIZE)) > 0) {
		write(result, buffer, nread);
	}

	close(source);
	close(result);
	exit(0);
}

예제 2

test.txt 파일 내용의 일부만 읽는 readmid.c 프로그램 작성
./readmid test.txt 처럼 파일이름은 명령행 인자로 받는다

test.txt

If I have seen further it is by standing on the shoulders of Giants.

→ “it is by standing” 만 읽어서 출력하는 프로그램 작성

#include <stdio.h>    
#include <stdlib.h>                                                  
#include <fcntl.h>                                                   
#include <unistd.h>    
    
int main(int argc, char *argv[])    
{    
    int fd = open(argv[1], O_RDONLY);
    char buffer[1024] = {0, };
    
    if (fd == -1) {
        printf("open error\n");
    }
    
    lseek(fd, 23, SEEK_SET);  // 23번째 글자로 파일 offset 지정
    read(fd, buffer, 17);  // 17글자를 읽는다
    printf("%s", buffer);
    
    close(fd);
    
    return 0;
}

예제 3

num.txt 에서 숫자를 읽어서 4의 배수인 경우 four.txt 파일로 저장하고 총 개수를 출력하는 getfour.c 프로그램 작성

파일 이름은 명령행 인자로 받는다.

#include <stdio.h>    
#include <stdlib.h>                                                  
#include <fcntl.h>                                                   
#include <unistd.h>    
    
int main(int argc, char *argv[])    
{    
    FILE *fp_source, *fp_dest;    
    int cnt = 0;   
		char line[100];
		int number; 
    
    fp_source = fopen(argv[1], "r");    
    fp_dest = fopen("four.txt", "w");    
    
    while(fgets(line, sizeof(line), fp_source) != NULL) {
        number = atoi(line);
        if(number % 4 == 0) {
		        cnt++;
            fprintf(fp_result, "%d\n", number);
				}
		}
    
    printf("%d\n", cnt);    

    fclose(fp_source);    
    fclose(fp_result);    
    
    return 0;    
}
profile
밀린 TIL 업로드 조금씩 정리중...

0개의 댓글