목적:

1. 실행파일을 gdb로 실행하면서 디버깅

# gdb [프로그램명]



2. 현재 실행중인 프로그램이 문제가 있는데.. 종료시키지 않고 디버깅 하고 싶다면..

attach 명령어를 사용해서 디버깅

먼저 디버깅할 프로세스의 PID를 구한다. 


#ps aux | grep [프로그램명]
root      4037  1.6  9.7 1909612 388600 ?      Ssl  Sep23 123:31 ./test_program

# gdb 

..중략..

(gdb) attach 4037


3. core파일을 디버깅

core파일을 생성하는 방법은 여러가지가 있는데요. 



3.1. gcore를 활용해서 core dump파일을 생성한 후 디버깅

#gdb -c [core파일명] [프로그램명] ,또는
#gdb [프로그램명][core파일명]

※ core dump 파일 만드는 방법은 단순히 gcore뒤에 core 파일을 만들 pid만 넣어주면 된다.

#gcore [-o filename] <pid>


3.2. gdb로 core파일을 생성하고 싶은 프로세스를 attach한 후 core dump파일 생성


(gdb) attach <pid>

(gdb) generate-core-file

Saved corefile core.<pid>


3.3. 실행중 segfault를 발생시키고 종료된 프로그램이 생성한 core파일이 있다면.. 


#gdb [프로그램명] [실행중인프로세스pid]


※ segfault 발생했을 때 core dump파일을 생성하도록 설정 하는 방법은 다음 포스트를 참조
http://kthan.tistory.com/45


 절차:

※ 컴파일시 -g 옵션을 사용해야 합니다. 


현재 위치에서 수행 가능한 명령어는 <tab>키를 누르면 조회됩니다. 

#gdb <binary>  

gdb를 실행하면 아래와 같은 프롬프트 화면이 나온다
(gdb)

"run"을 입력하면 프로그램이 실행된다.
만약 프로그램을 실행하는데 특정 옵션이 필요하다면 이곳에서 지정해줄 수 있다.
(gdb) run "--read /home/kthan/test.txt"
 

1. 프로그램이 비정상적으로 종료 되었다면..
스택을 보기 위해 bt(backtrace) 명령어를 사용한다. 현재 활성화된 서브루틴의 스택 프레임을 출력해준다.

 (gdb) bt

#0 Check (p=0x7fff9ffe3d10, lwssn=0x11b6bc20,
sPolicy=<value optimized out>, skey=<value optimized out>,    isnew=<value optimized out>) at stream.c:6858#1  Process (p=0x7fff9ffe3d10, lwssn=0x11b6bc20,

이런식으로 볼 수 있다. 
여기 나온 위치 값을 가지고 문제가 되는 소스의 위치를 알 수 있다. 


2. breaking point를 설정해서 원하는 만큼씩 실행하고 싶다면..실행하기 전에 먼저 breaking point를 설정한다. 

- func 함수의 시작위치에 설정
(gdb) b func 

-123번째 줄에 설정
(gdb) b 123   

-main.c 파일의 func 함수의 시작 위치에 설정
(gdb) b main.c:func 




설정한 breaking point는 "info b" 명령어로 조회 가능하다.

Num     Type      Disp Enb Address                                                         What

1       breakpoint     keep  y   0x0000000000444390 in SetupCompare at spo_check.c:178     breakpoint already hit 1 time
2       breakpoint     keep   y   0x0000000000441f80 in Setup    at spo_fast.c:116
3       breakpoint      keep  y   0x00000000004427c0 in Setup  at spo_full.c:99

Num: breakpoint의 고유번호
Type: breakpoint/watchpoint/catchpoint 정보
Disp: breakpoint의 특징
Enb: 현재 해당 breakpoint의 활성화 여부, 활성화/비활성화는 'enable br [Num]' 또는 'disable br [Num]'으로 변경가능


3. 원하는 원하는 만큼 위치를 옮겨가며 디버깅을 수행한다.

s(step) <반복횟수>  : 현재 출력된 행을 수행하고 멈추지만, 함수의 경우 함수의 내부로 들어가서 수행된다
 n(next)  : 현재 행을 수행하고 멈추지만, 함수의 경우 함수를 수행하고 넘어간다
 c(continue)  : 다음 브레이크 포인트를 만날때 까지 계속 수행한다
 u(until)  : for 문에서 빠져나와서 다음 브레이크 포인트까지 수행한다.
 finish : 현재 함수를 수행하고 빠져나감
 return : 현재 함수를 수행하지 않고 빠져나감
 return 123 : 현재 함수를 수행하지 않고 빠져나감, 단, 리턴값은 123
 si(step instruction)  : 현재의 인스트럭션을 수행, 함수 호출 시 내부로 들어간다.
 ni(next instruction)  : 현재의 인스트럭션을 수행, 함수 호출 시 내부로 들어가지 않는다.


4. 확인 해보고자 하는 값을 출력해가며 디버깅 수행

p(print) 변수 명 : 설정한 변수가 현재 가지고 있는 값을 출력
p *구조체 : 구조체의 값 출력

5. 종료
(gdb) quit


※gdb에 관한 고급 명령어는 다음 포스팅을 참고하세요.

 http://kthan.tistory.com/57

Posted by KT한
,

첫술에 배부르기를 기대하지 말고 단계 별로 차근차근 따라하면 

금방 vim을 자유자재로 사용할 수 있게 될겁니다. ^^  

Setp 1

기본 명령

내용입력모드로 진입 i
명령줄모드 :
명령모드로 진입 ESC
종료 :q
저장 :w
저장하고 종료 :wq 또는 :x
커서이동 h
l
k
j
한 단어 이동 w
공백으로 분리된 한 단어 이동 W
한 단어 뒤로 이동 b
공백으로 분리된 한 단어 뒤로 이동 B
문서 맨 끝 G
문서 맨 처음 gg

 선택된 문자 끝 

gn 

N번째 라인 :N
예) ":100", ":1"
지우기 한 글자 지우기 x
한 줄 지우기 dd
한 단어 지우기 dw
한 글자 지우고 입력모드로 전환 s
한 줄 지우고 입력모드로 전환 S

Setp 2

환경설정

기능 명령
tag 만들기 $ ctags -R .
$ cscope -Rbq

vim : 명령

일반

기능 명령
HELP 보기 :help

소스코드 추적

기능 명령
function call 따라가기 Ctrl-]
:cs find g <func_name>
function call 돌아오기 Ctrl-t
function reference 찾기 :cs find s <func_name>

Setp 3

환경설정

기능 명령
초기설정용 스크립트 파일 ~/.vimrc
tabstop :set ts=4
shiftwidth :set sw=4
auto indent :set ai
C style indent :set cin
background :set background=light|dark

vim 명령

일반

기능 명령
스크롤 한화면 Ctrl+f
Ctrl+b
화면절반 Ctrl+d
Ctrl+u
커서 이동 맨위 H
가운데 M
맨아래 L

Setp 4

화면분할

기능 명령
윈도우 상하분리 :split 또는 :sp
Ctrl+w s
좌우분리 :vsplit 또는 :vsp
Ctrl+w v
창 닫기 :q 또는 Ctrl+w q 또는 c
현재 커서가 있는 창 빼고 다 닫기 Ctrl+w o
윈도우간 커서 이동 Ctrl+w h,j,k,l
윈도우 위치이동 Ctrl+w H,J,K,L
창 크기 조절 Ctrl+ w [숫자] > 또는 < (숫자 만큼 창 크기 조절)
(옵션)멀티윈도우로 실행

-O2(수직분할), -o2(수평분할)

예) # vim -O2 main.c test.c 

모두저장 :wa
모두 종료 :qa

Setp 5

편집

기능 명령
자리표시/기억

m[a-z]
'm' 뒤에 누르는 키 이름으로 마킹 해둠. 

표시한 자리로 이동 '[a-z]
위에서 마킹한 키를 누르면 해당 위치로 이동함.
현재위치에서 위치 a 까지 지우기 d'a
현재위치에서 위치 a 까지 복사 y'a
화면스크롤 커서의 위치가 맨위로 가도록 z<CR>
커서의 위치가 가운데 zz
커서의 위치가 맨아래 z-
화면접기
편집명령아님.
화면만 변경
접기 zf<커서이동명령>
예: zf20j, zf%, zf'a
접은 화면 풀기 zo

Setp 6

편집

기능 명령
명령행에 붙이기 y...으로 복사한 다음 명령행에서 Ctrl+r[0-9]
예제:cs find s Ctrl+r 0
함수 자동 완성 함수명 일부 입력 후 Ctrl + n 또는 Ctrl + p
찾기 / 다음에 regex 사용 가능
커서자리의 스트링 찾기 아래방향 #
윗방향 *
바꾸기 커서있는 줄  :s/찾는문자열/바꿀문자열/g
마지막에 g는 두 개 이상 바꿀 때
문서전체 :%s/찾는문자열/바꿀문자열/g
참조: %대신 ^.,나 .,$
특정 위치 :10,20s/찾는문자열/바꿀문자열/g
참조: 10~20번째 줄에서만 찾아서 치환
한줄씩 스크롤 아래방향 Ctrl+e
윗방향 Ctrl+y

Setp 7

통합개발환경

기능 명령
빌드 :make
grep :grep ...
결과를 표시 :cl
특정 결과로 커서 이동 :cc번호
다음 결과로 커서 이동 :cn
이전 결과로 커서 이동 :cN
명령결과를 별도 창에 표시 :cw
명령결과창에 있는 내용으로 이동 커서 이동후 Enter


Posted by KT한
,
  • 목적: 

addr2line 은 바이너리 파일이 segfault를 내며 죽어버렸을 때 코드의 어떤 부분이 문제가 되는것인지 

찾을 때 유용하다.

사용하는 입장에서는 gdb와 유사하다고 볼 수 있는데.. gdb는 실행 전에 걸어야 한다는 점이 다르다고 볼 수 있다. 



  • 사용 절차:

1. 먼저 segfault가 난 상황이 발생하게 되면 .. 

2. segment fault가 발생한 시점을 찾아서 그 주소값을 복사한다 

$ ./test(_Z13segment_faultv+0×14) [0x400b64

$ ./test(main+0x2f) [0x400c2f]


3. #addr2line <주소> -fe <binary> 

ex) addr2line 400b64 -fe test


4. 결과로 출력된 위치로 이동해서 문제점을 찾는다.


Posted by KT한
,

1. 목적:  현재 시스템 상태정보를 보여준다.

2. 사용방법:
사용 가능한 명령어 리스트를 보고 싶다면 소문자 'h'를 눌러보자 

top - 16:53:50 up 45 days,  8:09, 22 users,  load average: 0.00, 0.00, 0.00
Tasks: 399 total,   1 running, 398 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.1%us,  0.1%sy,  0.0%ni, 99.8%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  12324804k total, 11996880k used,   327924k free,  2179864k buffers
Swap: 10289144k total,    82448k used, 10206696k free,  7375768k cached

▷ 이때 숫자 '1'을 누르면 전체 CPU에 대한 정보가 보여진다.
top - 16:55:44 up 45 days,  8:11, 22 users,  load average: 0.00, 0.00, 0.00
Tasks: 399 total,   1 running, 398 sleeping,   0 stopped,   0 zombie
Cpu0  :  0.0%us,  0.3%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu1  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu2  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu3  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu4  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu5  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

▷정렬 기준을 변경하고 싶다면 '<' 와 '>'키를 누르면 가능하다 

기본적으로 CPU사용률을 기준으로 정렬되어 있으며, 

'>'를 한 번 누르면 메모리 사용률을 기준으로 정렬이 된다. 



▷ 자주 사용하는 유용한 단축 키들 

H : thread별로 펼쳐서 정보를 보여준다.

N : PID로 정렬해서 보여준다. (numerically).

P : CPU사용률로 정렬해서 보여준다. (default).

M : 메모리 사용률로 정렬해서 보여준다. 

T : 실행 시간 순으로 정렬해서 보여준다.



▷화면에 보여지는 값들을 변경하고 싶다면 'f'를 눌러 설정하고자 하는 메뉴의 단축키를 눌러주면 설정 끝!
* A: PID        = Process Id
* E: USER       = User Name
* H: PR         = Priority
* I: NI         = Nice value
* O: VIRT       = Virtual Image (kb)
* Q: RES        = Resident size (kb)
* T: SHR        = Shared Mem size (kb)
* W: S          = Process Status
* K: %CPU       = CPU usage
* N: %MEM       = Memory usage (RES)
* M: TIME+      = CPU Time, hundredths
  b: PPID       = Parent Process Pid
  c: RUSER      = Real user name
  d: UID        = User Id
  f: GROUP      = Group Name
  g: TTY        = Controlling Tty
  j: P          = Last used cpu (SMP)
* P: SWAP       = Swapped size (kb)
  l: TIME       = CPU Time
  r: CODE       = Code size (kb)
  s: DATA       = Data+Stack size (kb)
  u: nFLT       = Page Fault count
  v: nDRT       = Dirty Pages count
  y: WCHAN      = Sleeping in Function
  z: Flags      = Task Flags <sched.h>
* X: COMMAND    = Command name/line

Posted by KT한
,