GNUEmacsManual:24

From 흡혈양파의 번역工房
Jump to: navigation, search
프로그램 컴파일 및 검사하기

프로그램 컴파일 및 검사하기

앞 절에서는 프로그램에 변경 사항을 적용하는 데에 유용한 Emacs 명령어를 논하였다. 이번 장에서는 프로그램을 컴파일하고 검사하는 과정에 도움이 되는 명령어를 다룬다.

Emacs에서 컴파일 실행하기

Emacs는 C, Fortran 과 같은 언어에 대한 컴파일러를 실행하여 컴파일 로그를 Emacs 버퍼로 feed할 수 있다. 또한 오류 메시지를 파싱하고 오류가 발생한 곳을 보여주기도 한다.


M-x compile
*compilation*
버퍼로 들어가는 오류 메시지와 함께 Emacs에서 비동기식으로 컴파일러를 실행한다.


M-x recompile
M-x compile 의 마지막 호출에서와 동일한 명령어로 컴파일러를 호출한다.


M-x kill-compilation
실행 중인 컴파일 하위프로세스를 제거한다.


make 또는 다른 컴파일 명령어를 실행하려면 M-x compile 을 입력한다. 이는 미니버퍼를 이용해 셸 명령 행을 읽은 후 셸을 Emacs 의 하위프로세스로 (또는 inferior process 로) 실행함으로써 명령어를 실행한다. 출력값은
*compilation*
이란 버퍼로 삽입된다. 현재 버퍼의 기본 디렉터리는 명령어 실행을 위한 작업 디렉터리로 사용되는데, 보통은 이 디렉터리에서 컴파일이 발생한다.


기본 컴파일 명령어는 make 유틸리티를 이용해 컴파일되는 프로그램에 적합한 '
make-k
' 이다('
-k
' 플래그는 make에게 오류 직후 가능한 한 많이 컴파일을 지속하라고 말한다.). GNU Make Manual 의 "Make" 절을 참고한다. 이전에 M-x compile 을 실행하였다면 사용자가 명시한 명령어는 자동으로
compile-command
변수에 보관되어 후에 사용자가 M-x compile 을 입력할 때 기본값으로 사용된다. 파일은
compile-command
에 대한 파일 로컬 값을 명시할 수도 있다(424 페이지의 33.2.4절 [파일 변수] 참고).


컴파일을 시작하면 다른 창에
*compilation*
버퍼를 표시하지만 그것을 선택하지는 않는다. 컴파일이 실행되는 동안 '
run
' 이라는 단어가
*compilation*
버퍼에 대한 주 모드 표시기(indicator)에 표시되며, '
Compiling
'이란 단어가 모든 모드 행에 나타난다. 컴파일이 실행되는 동안에는
*compilation*
버퍼를 표시된 채로 유지할 필요가 없으며, 어떤 경우라도 컴파일은 계속된다. 무슨 이유에서건 컴파일이 끝나면
*compilation*
버퍼의 모드 행은 '
exit
'(뒤에 종료 코드가 따라온다: 일반 종료는 '[0]') 또는 '
signal
'(신호가 프로세스를 종료한 경우)이라고 말하도록 변경된다.


컴파일 트랜스크립트가 나타날 때 지켜보고 싶다면
*compilation*
버퍼로 전환하여 포인트를 버퍼 끝으로 이동한다. 포인트가 끝에 있으면 새로운 컴파일 출력이 포인트 위로 삽입되어 끝에 남아 있는다. 그 외의 경우 포인트는 고정된 채로 남겨 출력은 버퍼 끝으로 추가된다.


compilation-scroll-output
변수를
nil
이 아닌 값으로 변경하면
*compilation*
버퍼가 자동으로 스크롤되어 출력을 따라간다. 값이
first-error
일 경우 첫 번째 오류가 나타날 때 스크롤이 중단되어 해당 오류에 포인트를 남겨둔다. 그 외 nil이 아닌 값의 경우 더 이상 출력이 없을 때까지 스크롤이 계속된다.


동일한 명령어로 마지막 컴파일로 돌아가려면 M-x recompile 을 입력한다. 이는 M-x compile 의 마지막 호출로부터 컴파일 명령어를 재사용한다.
*compilation*
버퍼도 재사용하여 기본 디렉터리에서 컴파일을 시작하는데, 이는 이전 컴파일이 시작된 것과 동일한 디렉터리다.


새로운 컴파일을 시작하면
*compilation*
에 이미 실행 중인 컴파일을 제거하기도 하는데, 버퍼는 언제든 하나의 컴파일만 처리할 수 있기 때문이다. 하지만 M-x compile 은 실행 중인 컴파일을 실제로 삭제하기 전에 컴파일에 대해 질문하는데,
compilation-always-kill
변수를
t
로 변경하면 컴파일에 대해 질문하지 않고 항상 자동으로 제거한다. M-x kill-compilation 명령어를 이용하면 컴파일 프로세스를 제거할 수도 있다.


한 번에 두 개의 컴파일을 실행하려면 첫 번째 컴파일을 시작해서
*compilation*
버퍼를 재명명하고 (아마도
rename-uniquely
를 이용해서(149 페이지의 16.3절 [다양한 버퍼]를 참고) 버퍼를 전환한 후 다른 컴파일을 시작한다. 그러면 새로운
*compilation*
버퍼를 생성할 것이다.


compilation-environment
변수를 이용해 컴파일 명령어도 전달되는 환경 변수를 관리할 수도 있다. 그 값은 환경 변수 설정으로 이루어진 목록으로, 각 요소는 "
envvarname=value
" 형태로 된 문자열이어야 한다. 이러한 환경 변수 설정은 일반 설정을 오버라이드한다.


Compilation 모드

*compilation*
버퍼는 Compilation 모드라고 불리는 주 모드를 사용한다. Compilation 모드는 버퍼 내 각 오류 메시지를 하이퍼링크로 바꾸는데, 그곳으로 포인트를 이동하여 RET 을 입력하거나 마우스로 클릭하면 구분된 창에 오류 메시지의 위치에 방문할 수 있다(164 페이지 18.3절의 [마우스 참조] 참고). 위치는 파일 내에서 해당 오류가 발생한 구체적인 위치다.


compilation-auto-jump-to-first-error
변수를
nil
이 아닌 값으로 변경하면 Emacs 는
*compilation*
버퍼에 나타나는 첫 오류 메시지의 위치로 자동 방문한다.


컴파일 모드는 아래의 추가 명령어를 제거한다. 이러한 명령어는
*grep*
버퍼에서도 사용 가능한데, 이 버퍼에서 하이퍼링크는 오류 메시지보다는 검색 일치 결과이다(264 페이지의 24.4절 [Grep 검색] 참고).


M-g M-n
M-g n
C-x '
텍스트 오류 메시지 또는 일치 결과의 위치를 방문한다(
next-error
).


M-g M-p
M-g p
이전 오류 메시지 또는 일치 결과의 위치를 방문한다(
previous-error
).


M-n
다음 오류 메시지 또는 일치 결과를 방문하지 않고 포인트를 그곳으로 이동한다(
compilation-next-error
).


M-p
이전 오류 메시지 또는 일치 결과를 방문하지 않고 포인트를 그곳으로 이동한다(
compilation-previous-error
).


M-}
포인트를 다른 파일에서 발생하는 다음 오류 메시지 또는 일치 결과로 이동한다 (
compilation-next-file
).


M-{
포인트를 다른 파일에서 발생하는 이전 오류 메시지 또는 일치 결과로 이동한다(
compilation-previous-file
).


C-c C-f
컴파일 버퍼에서 커서 움직임이 자동 소스 표시를 생성하는 Next Error Follow 부 모드를 토글한다.


오류를 순차적으로 방문하려면 C-x ' (
next-error
) 또는 그와 동일한 M-g M-n 또는 M-g n 을 입력한다. 이 명령어는 Compilation 모드 버퍼뿐 아니라 어떠한 버퍼에서든 호출이 가능하다. 컴파일 이후 이것을 처음으로 호출하면 첫 번째 오류 메시지의 위치(locus)를 방문한다. 이후 C-x ' 를 사용할 때마다 비슷한 방식으로 다음 오류를 방문한다.
*compilation*
버퍼에서 마우스 클릭이나 RET 을 이용해 특정 오류를 방문할 경우 잇따라 C-x ' 명령어를 사용하면 그곳에서부터 진행된다(advance). C-x ' 가 방문할 오류 메시지를 더 이상 발견하지 못하면 오류를 보낸다. C-u C-x ' 는 컴파일 버퍼의 시작부터 다시 시작하여 첫 번째 위치를 방문한다.


M-g M-p 또는 M-g p (
previous-error
)는 오류를 반대 방향으로 반복한다.


next-error
previous-error
명령어는
*compilation*
*grep*
버퍼에 열거된 오류 또는 일치 결과에만 실행되는 것이 아니라 M-x occur 를 비롯해 다른 명령어들이 생성한 오류 또는 일치 결과 목록을 반복하는 방법도 알고 있다(107 페이지의 12.11절 [기타 반복 검색] 참고). 오류 메시지 또는 일치 결과를 포함한 버퍼에 이미 있다면 그러한 오류 메시지 또는 일치 결과를 먼저 반복하고, 그 외의 경우 Emacs 는 선택된 프레임의 창 중에서 오류 메시지나 일치 결과를 포함한 버퍼를 검색한 다음
next-error
또는
previous-error
가 이전에 반복한 버퍼를 검색하고, 마지막으로 다른 모든 버퍼들 중에서 검색한다. 반복에 선택된 버퍼가 현재 창에 표시되지 않았다면 이제 표시될 것이다.


기본적으로
next-error
previous-error
명령어는 덜 중요한 메시지를 건너뛴다.
compilation-skip-threshold
변수는 이를 제어한다. 기본값 1은 경고보다 중요하지 않은 것은 건너뜀을 의미한다. 값이 2이면 오류보다 덜 중요한 것은 모두 건너뛰고, 0 은 어떠한 메시지도 건너뛰지 않음을 의미한다.


Emacs 가 오류 메시지가 발생한 장소로 방문하면 일시적으로 관련된 소스 행을 강조한다. 강조하는 시간은
next-error-highlight
변수로 결정된다.


*compilation*
버퍼가 왼쪽 fringe 와 함께 창에 표시되면 (81 페이지의 11.14절 [Fringes] 참고) 장소를 방문하는 명령어는 fringe 에 화살표를 놓고 현재 오류 메시지를 가리킨다. 텍스트 터미널처럼 창에 왼쪽 fringe 가 없다면 이러한 명령어들은 창을 스크롤하여 현재 메시지가 창의 상단에 위치하도록 한다.
compilation-context-lines
변수를 정수 값 n 으로 변경할 경우, 이러한 명령어들은 fringe 의 존재 유무와 상관없이 현재 오류 메시지가 상단에서 n 개의 행이 되도록 창을 스크롤하는데, 기본값인
nil
은 위에서 설명한 행위를 제공한다.


컴파일러로부터 메시지를 파싱하기 위해 Compilation 모드는 다양한 오류 메시지 포맷을 열거하고 Emacs 에게 각각으로부터 장소를 압축 해제(extract)하는 방법을 알려주는
compilation-error-regexp-alist
변수를 이용한다. 이와 유사한 변수인
grep-regexp-alist
는 grep 명령어로부터 출력값을 파싱하는 방법을 Emacs 에게 알려준다(264 페이지의 24.4절 [Grep 검색] 참고).


Compilation 모드는 SPCDEL 키를 화면만큼 스크롤하도록 정의하기도 하는데, M-n (
compilation-next-error
) 와 M-p (
compilation-previous-error
) 는 다음 또는 이전 오류 메시지로 이동하고, M-{ (
compilation-next-file
)과 M-} (
compilation-previous-file
)은 다른 소스 파일에 대한 다음 또는 이전 오류 메시지로 이동한다.


C-c C-f 를 입력하면 Next Error Follow 모드를 토글할 수 있다. 해당 부 모드의 경우, 컴파일 버퍼에서 일반적인 커서 움직임은 자동으로 소스 버퍼를 업데이트하는데, 가령 커서를 오류 메시지 위로 이동시키면 오류가 발생한 장소가 표시될 것이다.


Compilation 모드의 기능들은 Compilation Minor 모드라고 불리는 부 모드에서도 이용할 수 있다. 이는 일반 컴파일 출력 버퍼뿐만이 아니라 여느 버퍼에서든 오류 메시지를 파싱하도록 해준다. M-x compilation-minor-mode 를 입력하면 부 모드를 활성화한다. 예를 들어 Rlogin 버퍼(393 페이지의 31.4.10절 [원격 호스트] 참고)에서 Compilation 부 모드는 FTP에 의해 자동으로 원격 소스 파일에 접근한다(122 페이지의 15.1절 [파일명] 참고).


컴파일을 위한 하위셸

M-x compile 명령어는 셸을 이용해 컴파일 명령어를 실행하지만 비대화형 셸에 대한 옵션을 명시한다. 이는 특히 셸이 어떠한 프롬프트도 없이 시작되어야 한다는 의미이기도 하다.
*compilation*
버퍼에 일반 셸 프롬프트가 보기에 흉하다고 생각된다면 프롬프트를 무조건적으로 설정함으로써 셸의 init 파일에서 실수를 범하였음을 의미한다. (이러한 init 파일은
.bashrc
,
.profile
, .
cshrc
,
.shrc
등으로 사용자가 사용하는 셸에 따라 좌우된다.) 셸 init 파일은 프롬프트가 이미 존재할 경우에만 프롬프트를 설정해야 한다. Bash에서 이를 실행하는 방법은 다음과 같다:
if [ "${PS1+set}" = set ] 
then PS1=... 
fi


csh에서 이를 실행하는 방법은 다음과 같다:

if ($?prompt) set prompt = ...


Emacs는 컴파일러 프로세스가 비동기식 하위프로세스를 시작할 것이라고 예상하지 않는데, 만일 예상될 때에는 주 컴파일러 프로세스가 종료된 이후에도 계속 실행될 경우 Emacs는 그것을 제거해야 하며, 제거하지 않을 시 그러한 출력이 Emacs에 도달하지 않을지도 모른다. 이러한 문제를 피하기 위해서는 하위프로세스가 종료될 때까지 주 컴파일 프로세스가 기다리도록 한다. 셸 스크립트에서는 아래와 같이 '
$!
'와 '
wait
'를 사용하면 된다:
(sleep 10; echo 2nd)& pid=$! 	# Record pid of subprocess 
echo first message
wait $pid			# Wait for subprocess


배경 프로세스가 컴파일 버퍼로 출력하지 않고, 사용자는 주 컴파일 프로세스가 종료될 때 그러한 프로세스가 제거되지 않도록 확보하기만 해도 된다면 아래로 충분하다:

nohup command; sleep 1


Emacs에서 Grep을 이용한 검색

Emacs 로부터 컴파일러를 실행하여 컴파일 오류가 있는 행을 방문할 수 있듯이
grep
을 실행하여 일치 결과가 발견된 행으로 방문할 수 있다. 이는
grep
가 보고한 일치 결과를 "오류"인 것처럼 취급하여 이루어진다. 출력 버퍼는 Grep 모드를 이용하는데, 이는 Compilation 모드의 변형 모드이다(262 페이지의 24.2절 [Compilation 모드] 참고).


M-x grep
M-x lgrep
Emacs 에서
grep
을 비동기식으로 실행하여 일치하는 행을
*grep*
버퍼에 열거한다.


M-x grep-find
M-x find-grep
M-x rgrep
find
를 통해
grep
을 실행하고 출력값을
*grep*
버퍼에 수집한다.


M-x zrgrep
zgrep
을 실행하여 출력값을
*grep*
버퍼에 수집한다.


M-x kill-grep
실행 중인
grep
하위프로세스를 제거한다.


grep
을 실행하기 위해서는 M-x grep 을 입력한 후
grep
을 실행하는 방법을 명시하는 명령 행을 입력한다.
grep
을 일반적으로 실행하면 제공하는 것과 동일한 인자를 사용하는데,
grep
스타일의 regexp (주로 셸의 특수 문자를 인용하기 위해 작은 따옴표를 사용) 뒤에 파일명이 따라오는데, 와일드카드를 사용할 수도 있다. M-x grep 에 대한 접두 인자를 명시할 경우 포인트 주변의 버퍼에서 태그를 찾아서 (299 페이지의 25.3절 [태그] 참고) 기본
grep
명령어에 넣는다.


사용자의 명령어는
grep
을 실행할 필요가 없으며 동일한 포맷으로 출력을 생성하는 셸 명령어를 사용할 수 있다. 가령
grep
명령어는 다음과 같이 이어서 사용할 수 있다:
grep -nH -e foo *.el | grep bar | grep toto


grep
으로부터 출력은
*grep*
버퍼로 들어간다. 그에 상응하는 행은 컴파일 오류와 마찬가지로 C-x ', RET 등을 이용해 원본 파일에서 찾을 수 있다.


일부 grep 프로그램은 강조를 목적으로 일치 결과 주변에 특수 마커를 출력하도록 '
--color
' 옵션을 허용한다. 이 기능은
grep-highlight-matches
t
로 설정하여 이용할 수 있다. 소스 버퍼에 일치 결과를 표시할 때는 전체 소스 행이 아니라 정확한 일치 결과가 표시될 것이다.


M-x grep-find (M-x find-grep 으로도 사용가능) 명령어는 M-x grep 과 유사하지만 명령어에 다른 초기 기본값을 제공한다는 점에서 차이가 있는데, 이러한 기본값은 디렉터리 트리 내 모든 파일을 검색하도록
find
grep
을 모두 실행한다. 327 페이지의 27.15절 [Dired와 찾기]에서
find-grep-dired
명령어도 참고한다.


M-x lgrep (로컬 grep)과 M-x rgrep(재귀적 grep) 명령어는 사용자에 더 친화적인 버전의
grep
grep-find
로, 일치할 정규 표현식, 검색할 파일, 검색할 기본 디렉터리를 따로 요청한다. 검색의 대, 소문자 민감성은
case-fold-search
의 현재 값으로 제어된다. M-x zrgrep 명령어는 M-x rgrep 과 비슷하지만 gzipped 파일의 내용을 검색하는 데에
grep
대신
zgrep
을 호출한다.


이러한 명령어들은
grep-template
(
lgrep
용) 과
grep-find-template
(
rgrep
용) 변수를 기반으로 셸 명령어를 빌드한다. 검색할 파일은
grep-files-aliases
변수에 정의된 별칭(aliases)을 사용할 수 있다.


grep-find-ignored-directories
변수에 열거된 디렉터리는 M-x rgrep 이 자동으로 건너뛴다. 기본값은 다양한 버전 관리 시스템이 사용하는 데이터 디렉터리를 포함한다.


상황에 따른 구문 오류 찾기

Flymake 모드는 C, C++, Perl, HTML, TeX/LaTeX 를 포함해 다수의 프로그래밍 및 마크업 언어를 대상으로 상황에 맞는 구문 검사를 실행하는 부 모드이다. 이것은 비슷한 방식으로 일반 인간 언어에 맞춤법 검사를 실행하는 Flyspell 모드와 다소 비슷하다(111 페이지의 13.42절 [맞춤법] 참고). 파일을 편집하는 동안 Flymake 모드는 버퍼의 임의 사본을 이용해 배경에서 적절한 구문 검사 툴을 실행한다. 이후 오류 및 경고 메시지를 파싱하고, 버퍼에 오류 행을 강조한다. 사용되는 구문 검사 툴은 언어에 따라 좌우되는데, C/C++ 파일의 경우 주로 C 컴파일러가 된다. Flymake는 복잡한 프로젝트를 검사하기 위해 make와 같은 빌드 툴을 이용할 수도 있다.


Flymake 모드를 활성화하려면 M-x flymake-mode 를 입력한다. M-x flymake-go-to-next-errorM-x flymake-goto-prev-error 를 이용해 그것이 찾는 오류로 건너뛸 수도 있다. 현재 행과 관련된 오류 메시지를 표시하려면 M-x flymake-display-err-men-for-current-line 을 입력한다.


Flymake 의 이용에 관한 추가 정보는 Emacs 와 함께 배포되는 Flymake Info 매뉴얼을 참고한다.


Emacs에서 디버거 실행하기

GUD(Grand Unified Debugger) 라이브러리는 다양한 심볼릭 디버거에 대한 Emacs 인터페이스를 제공한다. 이는 GNU Debugger(GDB)를 비롯해 DBX, SDB, XDB, Perl 의 디버깅 모드, Python 디버거 PDB, Java Debugger JDB 를 실행한다.


Emacs는 디버깅된 프로그램의 상태를 표시하기 위해 추가 Emacs 창을 사용하는 특수 인터페이스를 GDB 로 제공한다. 270 페이지의 24.6.5절 [GDB 그래픽 인터페이스]를 참고한다.


Emacs는 Emacs Lisp 프로그램에 대해 빌트인된 디버거를 갖고 있다. the Emacs Lisp Reference Manual 의 "The Lisp Debugger"절을 참고한다.


GUD 시작하기

디버거 하위프로세스를 시작하는 명령어에는 몇 가지가 있으며, 각각은 특정 디버거 프로그램에 해당한다.


M-x gdb
GDB를 하위프로세스로서 실행하고, 유사 IDE Emacs 인터페이스를 통해 상호작용한다. 이 명령어에 대한 추가 정보는 270 페이지의 24.6.5절 [GDB 그래픽 인터페이스]를 참고한다.


M-x gud-gdb
GDB 하위프로세스로와 입출력에 GUD 상호작용 버퍼를 이용해 GDB를 실행한다(267 페이지의 24.6.2절 [디버거 연산] 참고). 그러한 버퍼가 이미 존재할 경우 그것으로 전환하고, 그렇지 않으면 버퍼를 생성하여 전환한다.
목록 내 다른 명령어들도 다른 디버거 프로그램에 대해 동일하게 실행한다.


M-x perldb
디버그 모드에서 Perl 인터프리터를 실행한다.


M-x jdb
Java 디버거를 실행한다.


M-x pdb
Python 디버거를 실행한다.


M-x dbx
DBX 디버거를 실행한다.


M-x xdb
XDB 디버거를 실행한다.


M-x sdb
SDB 디버거를 실행한다.


이러한 명령어 각각은 디버거를 호출하기 위해 미니버퍼를 이용해 명령어를 읽는다. 미니버퍼의 초기 내용에는 표준 실행 파일명과 디버거에 대한 옵션이 포함되어 있으며, 때로는 사용자가 디버깅하고자 하는 실행 파일명의 짐작을 포함하기도 한다. 셸 와일드카드와 변수는 이 명령 행에 허용되지 않는다. Emacs는 '-'로 시작하지 않는 첫 번째 명령어 인자가 실행 파일명이라고 가정한다.


Tramp는 디버거와 디버깅되는 프로그램이 동일한 원격 호스트 상에 있는 원격 디버깅을 위한 기능을 제공한다. The Tramp Manual의 "Running a debugger on a remote host" 절에서 자세한 내용을 참고한다. 이는 프로그램과 디버거가 다른 머신에서 실행되는 GDB의 원격 디버깅 기능과는 구분된다(The GNU debugger 의 "Debugging Remote Programs"절을 참고).


디버거 연산

GUD 상호작용 버퍼(GUD interaction buffer) 는 디버거 하위프로세스로 텍스트 명령어를 전송하여 그 출력을 기록하는 데에 사용되는 Emacs 버퍼이다. 이것은 M-x gud-gdb 와 앞 절에 열거된 다른 명령어들이 사용하는 디버거와 상호작용을 하기 위한 기본 인터페이스이다. M-x gdb 명령어는 이 인터페이스를 중단점, 스택 프레임, 그 외 디버거 상태 측면들을 제어하도록 특수화된 추가 버퍼들을 이용해 확장한다(270 페이지의 24.6.5절 [GDB 그래픽 인터페이스]).


GUD 상호작용 버퍼는 Shell 모드의 변형 모드를 사용하여 Shell 모드에서 정의한 Emacs 명령어들을 이용할 수 있다(385 페이지의 31.4.3절 [셸 모드] 참고). 완성은 대부분 디버거 명령어에서 이용 가능하며 (28 페이지의 5.4절 [완성] 참고) 사용자는 그것을 반복하기 위해 일반적인 Shell 모드 히스토리 명령어를 이용할 수 있다. GUD 상호작용 버퍼에서 사용할 수 있는 특수 명령어는 다음 절을 참고한다.


프로그램을 디버깅하는 동안 Emacs는 Emacs 버퍼에서 관련된 소스 파일을 방문하여 표시하는데, 현재 실행 행은 왼쪽 여백에 화살표가 표시된다. (텍스트 터미널에서 화살표는 첫 두 개의 텍스트 열에 '
=>
',로 오버레이되어 있다.) 그러한 버퍼로 포인트를 이동 시 화살표를 움직이지 않는다. 이러한 소스 파일을 원하는 대로 편집할 수는 있지만 행을 삽입하거나 삭제하는 것은 행의 위치 조정을 혼동시킬 것인데, Emacs는 어떤 편집된 소스 행이 디버거 하위프로세스가 보고한 행에 일치하는지 알아낼 방법이 없기 때문이다.


GUD Tooltip 모드는 GUD 에게 툴팁 지원을 추가하는 전역적 부 모드이다. 이 모드를 토글하려면 M-x gud-tooltip-mode 를 입력한다. 이는 기본적으로 비활성화되어 있다. 활성화되어 있다면 마우스 커서를 변수, 함수 또는 매크로 (전체적으로 식별 문자라고 부름) 위로 이동시켜 그 값을 툴팁에 표시하도록 한다(174 페이지의 18.17절 [툴팁] 참고). 아니면 식별 문자 또는 표현식 위로 마우스를 드래그하여 마크한 후 툴팁에 표시된 표현식 값을 가지려면 마크된 영역에서 마우스를 드롭한다. GUD Tooltip 모드는 GUD 상호작용 버퍼에 적용되며,
gud-tooltip-modes
변수에 열거된 주 모드가 있는 모든 소스 버퍼에도 적용된다.
gud-tooltip-echo-area
변수가
nil
이 아닐 경우 또는 사용자가 툴팁 모드를 끌 경우 툴팁 대신 그 값이 에코 영역에 표시된다.


M-x gud-gdb 와 함께 GUD Tooltip 모드를 이용할 경우 GDB에 표현식의 값을 표시하면 때때로 매크로를 확장시켜 디버깅된 프로그램에 부작용을 초래할 가능성이 있다. 그러한 이유로
gud-gdb
에서 툴팁의 이용은 비활성화된다. M-x gdb 인터페이스를 사용할 경우 부작용을 피하는 특별한 코드가 존재하기 때문에 그러한 문제는 발생하지 않을 뿐 아니라 사용자는 프로그램이 실행되지 않을 때 식별 문자와 관련된 매크로 정의를 표시할 수 있다.


GUD의 명령어

GUD는 중단점을 설정, 제거하고, 스택 프레임을 선택하며, 프로그램을 step through하기 위한 명령어를 제공한다.


C-x C-a C-b
포인트가 위치한 소스 행에서 중단점을 설정한다.


C-x C-a C-b (
gud-break
)를 소스 버퍼에서 호출하면 현재 소스 행에 디버거 중단점을 설정한다. 이 명령어는 GUD를 시작한 이후에만 이용 가능하다. 어떠한 디버거 하위프로세스와도 관련되지 않은 버퍼에서 호출할 경우 오류가 발생한다.


아래 명령어들은 GUD 상호작용 버퍼와 전역적으로 모두 이용 가능하지만 다른 키 바인딩을 사용한다. C-c 로 시작하는 키는 GUD 상호작용 버퍼에서만 이용 가능한 반면 C-x C-a 로 시작되는 키는 전역적으로 이용 가능하다. 이러한 명령어들 중 일부는 툴 바를 통해 이용할 수도 있지만 일부는 특정 디버거에서 지원하지 않는다.


C-c C-l
C-x C-a C-l
GUD 상호작용 버퍼에서 마지막으로 참조된 소스 행을 다른 창에 표시한다(
gud-refresh
).


C-c C-s
C-x C-a C-s
다음 단일 코드 행을 실행한다(
gud-step
). 행이 함수 호출을 포함할 경우 실행은 호출된 함수를 입력한 이후에 중단된다.


C-c C-n
C-x C-a C-n
다음 단일 코드 행을 실행하고, 함수 내에서 중지하지 않고 함수 호출 간 단계를 건너(step across)뛴다(
gud-next
).


C-c C-i
C-x C-a C-i
단일 머신 지시어를 실행한다(
gud-stepi
).


C-c C-p
C-x C-a C-p
포인트에서 표현식을 평가한다(
gud-print
). 사용자가 정확히 원하는 표현식을 Emacs가 출력하지 않으면 그것을 영역으로 먼저 마크한다.


C-c C-r
C-x C-a C-r
중지점을 명시하지 않고 실행을 계속한다. 중단점에 도달할 때, 종료할 때, 또는 디버거가 (
gud-cont
)를 검사하고 있다는 신호를 받을 때까지 프로그램이 실행될 것이다.


C-c C-d
C-x C-a C-d
현재 소스 행에 중단점이 있을 경우 삭제한다(
gud-remove
). 이 명령어를 GUD 상호작용 버퍼에서 사용하면 프로그램이 마지막으로 중단된 행에 적용된다.


C-c C-t
C-x C-a C-t
현재 소스 행에 임시 중단점이 있을 경우 설정한다(
gud-tbreak
). 이 명령어를 GUD 상호작용 버퍼에서 사용하면 프로그램이 마지막으로 중단된 행에 적용된다.


C-c <
C-x C-a <
마지막 포함하는 스택 프레임을 선택한다(
gud-up
). 이는 GDB 명령어 '
up
'과 같다.


C-c >
C-x C-a >
다음 내부 스택 프레임을 선택한다(
gud-down
). 이는 GDB 명령어 '
down
'과 같다.


C-c C-u
C-x C-a C-u
현재 행으로 실행을 계속한다(
gud-until
). 프로그램은 중단점에 도달할 때, 종료될 때, 디버거가 검사하고 있다는 신호를 받을 때, 또는 커서가 현재 위치한 행에 도달할 때까지 실행될 것이다.


C-c C-f
C-x C-a C-f
선택된 스택 프레임이 반환되거나 어떠한 이유로 중단될 때까지 프로그램을 실행한다 (
gud-finish
).


GDB를 사용 중이라면 이 추가 키 바인딩이 이용 가능하다:

C-x C-a C-j
소스 버퍼에서만 유용하며,
gud-jump
는 프로그램의 실행점을 현재 행으로 이동한다. 다시 말해, 프로그램이 실행하는 다음 행은 사용자가 명령어를 제공하는 행이다. 새로운 실행 행은 이전 실행 행과 다른 함수에 위치하며, 결과가 이상한 경우에는 GDB가 확인을 요할 것이다.
jump
에 관한 상세한 내용은 GDB 매뉴얼 엔트리를 참고한다.


TAB
GDB 를 이용해 심볼명을 완성한다(
gud-gdb-complete-command
). 이 키는 GUD 상호작용 버퍼에서만 이용할 수 있다.


이러한 명령어들은 가능할 경우 수치적 인자를 반복 계수로 해석한다.


TAB 은 완성 명령어 역할을 하므로 사용자가 GDB 로 디버깅하는 프로그램에 대한 입력값으로 탭을 입력하는 데에 사용할 수 없다. 대신 탭을 입력하려면 C-q TAB 을 입력한다.


GUD 맞춤화

GUD 는 시작 시 다음 훅 중 하나를 실행한다: GDB 를 이용 중일 경우
gdb-mode-hook
, DBX 를 이용 중일 경우
dbx-mode-hook
; SDB 를 이용 중일 경우,
sdb-mode-hook
; XDB 를 이용 중일 경우,
xdb-mode-hook
; Perl 디버깅 모드를 이용 중일 경우,
perldb-mode-hook
; PDB 를 이용 중일 경우,
pdb-mode-hook
; JDB 를 이용 중일 경우
jdb-mode-hook
. 422 페이지의 33.2.2절 [훅]을 참고한다.


gud-def
Lisp 매크로(Emacs Lisp Reference Manual 의 "Defining Macros"절을 참고)는 특정 명령어 문자열을 디버거로 전송하는 Emacs 명령어를 편리하게 정의하는 방법을 제공하고, GUD 상호작용 버퍼에서 키 바인딩을 설정한다:
(gud-def function cmdstring binding docstring)


이는 디버거 프로세스로 cmdstring 을 전송하는 function 으로 명명된 명령어를 정의하여 그곳으로 문서 문자열 docstring 을 제공한다. 이후 function 명령어는 어떤 버퍼에서든 사용할 수 있다. binding
nil
값이 아닐 경우
gud-def
는 명령어를 GUD 버퍼의 모드에서 C-c binding 에 바인딩하며, 일반적으로는 C-x C-a binding 에 바인딩한다.


cmdstring 명령어 문자열은 function 이 호출되는 시간에 채워질 데이터를 의미하는 특정 '
%
'-시퀀스를 포함할 수 있다.


'%f'
현재 소스 파일의 이름. 현재 버퍼가 GUD 버퍼일 경우 "현재 소스 파일"은 프로그램이 위치하는 파일이다.


'%l'
현재 소스 행의 개수. 현재 버퍼가 GUD 버퍼일 경우 "현재 소스 행"은 프로그램이 위치하는 행이다.


'%e'
transient-mark-mode 에서 영역이 활성화되어 있을 경우 영역 내 텍스트. 활성화되어 있지 않은 경우 포인트에 위치하거나 포인트 주변에 위치한 함수 호출 표현식 또는 C lvalue의 텍스트.


'%a'
포인트에 위치하거나 포인트 주변에 위치한 16진 주소의 텍스트.


'%p'
호출된 함수의 수치적 인자에 해당하는 10진수. 수치적 인자 없이 명령어가 호출된 경우 '
%p
'는 빈 문자열을 의미한다.
명령어 문자열에 '
%p
'를 사용하지 않으면 사용자가 정의하는 명령어는 어떠한 수치적 인자도 무시한다.


'%d'
현재 소스 파일의 디렉터리명.


'%c'
포인트를 둘러싼 표현식에서 파생된 클래스명의 절대 표기(fully qualified class name) (jdb만 해당).


GDB 그래픽 인터페이스

M-x gdb 명령어는 유사 IDE 인터페이스에서 GDB를 시작하는데, 여기에는 중단점, 스택 프레임, 그 외 디버거 상태의 측면을 관리하는 특수화된 버퍼들이 있다. 또한 GDB는 중단점을 설정하기 위해 소스 버퍼의 fringe에서 클릭하는 것과 같이 마우스를 이용해 디버깅 세션을 통제하는 방법도 추가로 제공한다.


추가 기능 없이 GUD 상호작용 버퍼 인터페이스만 이용하여 GDB를 실행하기 위해서는 M-x gud-gdb 를 사용한다(266 페이지의 24.6.1절 [GUD 시작하기] 참고). 이는 하나의 Emacs 세션 내에서 다수의 프로그램을 디버깅할 때 사용하면 좋은데, M-x gdb 에서 현재 지원하지 않기 때문이다.


내부적으로 M-x gdb 는 GDB에게 그 "화면 크기"가 제한되어 있지 않음을 알리는데, 올바른 작동을 위해서는 사용자가 디버깅 세션 중에 GDB 화면의 높이 및 너비 값을 변경해야 한다.


GDB 사용자 인터페이스 레이아웃
gdb-many-windows
변수가
nil
(기본값)일 경우 M-x gdb 는 보통 GUD 상호작용 버퍼만 표시한다. 하지만
gdb-show-main
변수 역시
nil
이 아닐 경우 2개의 창을 시작하는데, 하나는 GUD 상호작용 버퍼를 표시하고 나머지 하나는 사용자가 디버깅 중인 프로그램의 main 함수에 대한 소스를 표시한다.


gdb-many-windows
nil
값이 아닐 경우 M-x gdb 는 다음 프레임 레이아웃을 표시한다:
+--------------------------------+--------------------------------+
|   GUD interaction buffer       |   Locals/Registers buffer      |
|--------------------------------+--------------------------------+
|   Primary Source buffer        |   I/O buffer for debugged pgm  |
|--------------------------------+--------------------------------+
|   Stack buffer                 |   Breakpoints/Threads buffer   |
+--------------------------------+--------------------------------+


사용자가 창 레이아웃을 변경한 적이 있다면 M-x gdb-restore-windows 를 입력하여 "다중 창" 레이아웃을 복구할 수 있다. 다중 창 레이아웃과 GUD 상호작용 버퍼 및 소스 파일만 있는 단순한 레이아웃을 토글하려면 M-x gdb-many-windows 를 입력한다.


동일한 프레임 또는 다른 프레임에 표시할 추가 GDB와 관련된 버퍼를 명시할 수도 있다. 원하는 버퍼는 M-x gdb-display-buffertype-buffer 또는 M-x gdb-frame-buffertype-buffer 를 입력하면 되는데, 여기서 buffertype 은 '
breakpoints
'와 같이 상관된 버퍼 타입을 나타낸다. 메뉴 바도 마찬가지로 실행이 가능하며, 'GUD' 메뉴의 '
GDB-Windows
'와 '
GDB-Frames
' 하위메뉴를 이용한다.


디버깅이 완료되면 C-x k 를 이용해 GUD 상호작용 버퍼를 제거하면 세션과 관련된 버퍼 역시 모두 제거할 것이다. 하지만 Emacs 내에서 소스 코드를 편집하고 재컴파일한 후에 디버깅을 계속하고 싶을 경우에는 이를 실행할 필요가 없다. 실행을 다시 시작하면 GDB는 자동으로 새로운 실행 파일을 찾는다. GUD 상호작용 버퍼에는 GDB의 중단점뿐만 아니라 셸 히스토리 역시 보관한다는 장점이 있다. 최근 편집한 소스 파일에서 중단점이 올바른 위치에 있는지 확인할 필요가 없다.


소스 버퍼
Mouse-1
(fringe에서) 해당 행에 중단점을 설정 또는 삭제한다.


C-Mouse-1
(fringe에서) 해당 행에 중단점을 활성화 또는 비활성화한다.


Mouse-3
(fringe에서) 해당 행에서 실행을 계속한다.


C-Mouse-3
(fringe에서) 해당 행으로 점프한다.


그래픽 디스플레이에서 소스 버퍼의 fringe에 Mouse-1 을 클릭하면 해당 행에서 중단점을 설정한다(81 페이지의 11.14절 [Fringes] 참고). 사용자가 클릭한 곳에 빨간 점이 나타난다. 중단점이 이미 그 자리에 존재할 경우 클릭을 하면 제거된다. C-Mouse-1 클릭은 기존 중단점을 활성화 또는 비활성화시키고, 비활성화되었지만 설정 해제되지 않은 중단점은 회색 점으로 표시된다.


텍스트 터미널에서 또는 fringes가 비활성화되면 활성화된 중단점은 창의 왼쪽 여백에 '
B
' 문자가 표시된다. 비활성화된 중단점은 '
b
'로 표시된다. (중단점이 존재할 경우에만 여백이 표시된다.)


소스 버퍼의 왼쪽 fringe에 있는 굵은 화살표는 디버깅된 프로그램이 중단된 가장 안쪽의 프레임의 행을 나타낸다. 빈 화살표는 고수준 프레임의 현재 실행 행을 나타낸다. Mouse-1 을 이용해 fringe에서 화살표를 드래그할 경우 버튼을 해제하는 행으로 실행을 진행(advance)하게 된다. 또 fringe에서 Mouse-3 을 클릭하게 되면 그 행으로 진행한다. Fringe에서 C-Mouse-3 을 클릭하면 중간 행을 실행하지 않고 해당 행으로 점프할 수 있다. 이 명령어는 뒤로 돌아갈 수 있도록 해주는데, 이는 이미 실행된 코드를 좀 더 자세히 보는 데에 유용하다.


중단점 버퍼

GDB Breakpoints 버퍼는 중단점, watchpoint, catchpoint를 디버거 세션에서 표시한다. The GNU debugger 의 "Breakpoints" 절을 참고한다. 이는 다음과 같은 명령어들을 제공하는데, 이러한 명령어들은 대부분 현재 중단점에 적용된다(포인트가 위치한 중단점):


SPC
현재 중단점을 활성/비활성화한다(
gdb-toggle-breakpoint
). 그래픽 디스플레이에서 이것은 해당 행에 소스 버퍼의 fringe 에 있는 점 색을 변경시킨다. 중단점이 활성화되면 점은 빨간색, 비활성화되면 회색이다.


D
현재 중단점을 삭제한다(
gdb-delete-breakpoint
).


RET
현재 중단점에 대한 소스 행을 방문한다(
gdb-goto-breakpoint
).


Mouse-2
사용자가 클릭하는 중단점에 대한 소스 행을 방문한다.


gdb-many-windows
nil
값이 아닐 경우, GDB Breakpoints 버퍼는 그 창을 GDB Threads 버퍼와 공유한다. 둘을 전환하려면 제목 행에 위치한 관련 버튼에서 Mouse-1 로 클릭한다.
gdb-show-threads-by-default
nil
이 아닐 경우 GDB Threads 버퍼가 기본적으로 표시된다.


Threads 버퍼
GDB Threads 버퍼는 디버깅된 프로그램에 쓰레드 요약을 표시한다. The GNU debugger의 "Debugging programs with multiple threads" 절을 참고한다. 쓰레드를 선택하려면 포인트를 그곳으로 이동시켜 RET (
gdb-select-thread
)를 누르거나 Mouse-2 로 클릭한다. 이는 관련된 소스 버퍼를 표시하고, 다른 GDB 버퍼들의 내용을 업데이트한다.


gdb-buffers
그룹의 변수를 맞춤화하여 GDB Threads 버퍼에 포함된 필드를 선택한다.


gdb-thread-buffer-verbose-names
'
Thread 0x4e2ab70 (LWP 1983)
'와 같은 긴 쓰레드명을 표시한다.


gdb-thread-buffer-arguments
쓰레드 상단 프레임의 인자를 표시한다.


gdb-thread-buffer-locations
파일 정보 또는 라이브러리명을 표시한다.


gdb-thread-buffer-addresses
쓰레드 버퍼에서 쓰레드 프레임에 대한 주소를 표시한다.


여러 개의 쓰레드에 대한 정보를 동시에 보기 위해서는 GDB Threads 버퍼로부터 다음 명령어를 사용한다.


d
현재 행에 쓰레드에 대한 어셈블리 버퍼를 표시한다(
gdb-display-disassembly-for-thread
).


f
현재 행에 쓰레드에 대한 GDB Stack 버퍼를 표시한다(
gdb-display-stack-for-thread
).


l
현재 행에 쓰레드에 대한 GDB Locals 버퍼를 표시한다(
gdb-display-locals-for-thread
).


r
현재 행에 쓰레드에 대한 GDB Registers 버퍼를 표시한다(
gdb-display-registers-for-thread
).


저 문자들의 대문자
D
,
F
,
L
,
R
은 위의 각 버퍼를 새 프레임에 표시한다.


사용자가 특정 쓰레드에 관한 정보를 표시하는 버퍼를 생성할 때 그것은 해당 쓰레드에 바인딩되고 사용자가 프로그램을 디버깅하는 동안 실제 정보를 계속 표시한다. 각 GDB 버퍼에 대한 모드 표시기는 그것이 정보를 표시하는 쓰레드 개수를 보여준다. 쓰레드 개수는 바인딩된 버퍼의 버퍼명에도 포함되어 있다.


GDB Threads 버퍼에서는 프로그램의 실행을 제어하는 데에 사용되는 GDB 모드에 의존하는 추가 명령어들을 이용할 수 있다. 275 페이지의 24.6.5.8절 [다중 쓰레드 디버깅]을 참고한다.


Stack버퍼

GDB Stack 버퍼는 콜 스택(call stack)과 함께 디버거 세션에서 중첩된 하위루틴 호출(스택 프레임)마다 하나의 행을 표시한다. The GNU debugger의 "Backtraces" 절을 참고한다.


그래픽 디스플레이에서 선택된 스택 프레임은 fringe에서 화살표로 표시된다. 텍스트 터미널 또는 fringes가 비활성화되면 선택된 스택 프레임의 색상대비(reverse contrast)로 표시된다. 스택 프레임을 선택하려면 그 행으로 포인트를 이동시키고 RET (
gdb-frames-select
)를 입력하거나 그 위에서 Mouse-2 로 클릭한다. 이것이 완료되면 Locals 버퍼가 업데이트된다(다음 절에 설명).


기타 GDB 버퍼
Locals Buffer
이 버퍼는 단순한 데이터 타입에 대한 현재 프레임의 로컬 변수 값을 표시한다(The GNU debugger 의 "Information on a frame"절을 참고). 값을 편집하고 싶다면 RET 을 누르거나 값에서 Mouse-2 를 클릭한다.
배열과 구조는 그들의 타입만 나타낸다. GDB 6.4 버전부터는 RET 을 입력하거나 Mouse-2 클릭을 통해 포인트에 위치한 로컬 변수의 값을 조사할 수 있다. GDB 초기 버전의 경우 타입 설명에서 RET 또는 Mouse-2 를 사용한다('
[struct/union]
' 또는 '
[array]
'. 274 페이지의 24.6.5.7절 [Watch 표현식]을 참고한다.


Registers Buffer
해당 버퍼는 레지스터가 보유한 값을 표시한다(The GNU debugger의 "Registers" 절 참고). 레지스터 값을 편집하고 싶다면 레지스터 위에서 RET 을 누르거나 Mouse-2 를 클릭한다. GDB 6.4 버전부터는 font-lock-warning-face를 이용해 최근에 변경된 레지스터 값을 표시할 수 있다.


Assembler Buffer
어셈블리 버퍼는 현재 프레임을 머신 코드로 표시한다. 화살표는 현재 지시를 가리키며, 사용자는 중단점을 소스 버퍼에서와 같이 설정 및 제거할 수 있다. 중단점 아이콘은 fringe 또는 여백에도 나타난다.


Memory Buffer
메모리 버퍼는 프로그램 메모리의 섹션을 조사하도록 해준다(The GNU debugger의 "Examining memory" 절을 참고­). 제목 행의 적절한 부분에서 Mouse-1 을 클릭하면 버퍼가 표시하는 데이터 항목의 개수 또는 시작 주소를 변경할 수 있다. 아니면 각각 N과 S를 이용할 수도 있다. 제목 행에서 Mouse-3 을 클릭하여 이러한 데이터 항목들에 대한 unit 크기 또는 디스플레이를 선택한다.


gdb-many-windows가 nil이 아닐 경우 locals 버퍼는 중단점과 쓰레드 버퍼처럼 레지스터 버퍼와 창을 공유한다. 전환은 제목 행의 관련 버튼에서 Mouse-1 을 클릭하여 이루어진다.


표현식 지켜보기
프로그램이 중단될 때마다 변수가 어떻게 변하는지 보고 싶다면 포인트를 변수명으로 이동시키고 툴바의 watch 아이콘을 클릭하거나 (
gud-watch
) 또는 C-x C-a C-w 를 입력한다. 접두 인자를 명시하면 미니버퍼에 변수명을 입력할 수 있다.


각 watch 표현식은 스피드바에 표시된다(171 페이지의 18.9절 [스피드바] 참고). 배열, 구조, union과 같은 복잡한 데이터 타입은 트리 포맷으로 표현된다. 잎(leaves)과 단순한 데이터 타입은 표현식의 이름과 값을 표시하고, 스피드바 프레임이 선택되면 타입을 툴팁으로 표시한다. 상위수준은 포인터에 대한 이름, 타입, 주소 값을 표시하고, 그 외의 수준은 이름과 타입만 표시한다. 루트 표현식은 프레임 주소까지 툴팁으로 표시하여 그들이 정의된 프레임을 확인하도록 도와준다.


복잡한 데이터 타입을 확장하거나 축소하려면 태그에서 표현식 왼쪽으로 Mouse-2 를 클릭하거나 SPC 를 입력한다. Emacs는 직계 자녀의 개수가
gdb-max-children
변수의 값을 초과할 경우 표현식을 확장하기 전에 승인을 요청한다.


복잡한 watch 표현식을 삭제하려면 포인트를 스피드바의 루트 표현식으로 이동하여 D (
gdb-var-delete
)를 입력한다.


단순한 데이터 타입이나 복잡한 데이터 타입의 단순한 요소가 있는 변수를 편집하려면 스피드바의 해당 위치로 포인트를 이동시키고 RET(
gdb-edit-value
) 을 입력한다. 아니면 값에서 Mouse-2 를 클릭하여 편집할 수도 있다. 어떤 방식이든 이는 미니버퍼를 이용해 새 값을 읽는다.


gdb-show-changed-values
변수를
nil
이 아닌 값으로 (기본값) 설정하면 Emacs 는
font-lock-warning-face
를 이용하여 최근 변경된 값을 강조하고, 범위를 벗어난 변수를 눈에 덜 띄게 만들도록 face 를
섀도잉
(shadow)한다. 변수가 범위를 벗어나면 사용자는 그 값을 편집할 수 없다.


gdb-delete-out-of-scope
변수가
nil
이 아닌 값일 (기본값) 경우 Emacs 는 자동으로 범위를 벗어난 watch 표현식을 삭제한다. 가끔은 동일한 함수를 다시 들어갈 때 이 값을
nil
값으로 설정하면 사용자가 watch 표현식을 다시 생성할 필요가 없어서 유용하다.


gdb-use-colon-colon-notation
변수가
nil
값이 아닌 경우 Emacs 는 '
function::variable
' 포맷을 사용한다. 이는 동일한 변수명을 공유하는 watch 표현식을 표시할 수 있도록 허용한다. 이 변수의 기본값은 nil이다.


Watch 표현식의 디스플레이가 업데이트될 때마다 스피드바를 자동으로 표시(raise)하고 싶다면
gdb-speedbar-auto-raise
nil
이 아닌 값으로 설정한다. 이는 전체 화면의 Emacs 프레임으로 디버깅할 경우 유용하다.


다중 쓰레드 디버깅

GDB 의 all-stop mode에서는 프로그램이 중단될 때마다 모든 실행 쓰레드가 중지된다. 마찬가지로 사용자가 프로그램을 재시작할 때마다 모든 쓰레드는 실행을 시작한다. The GNU debugger 의 "All-Stop Mode" 절을 참고한다. 다중 쓰레드 대상에 대해 GDB는 디버거에서 중단된 프로그램 쓰레드를 조사하는 동시에 다른 쓰레드는 자유롭게 계속 실행되는 non-stop mode 라는 추가 연산 모드를 지원한다. The GNU debugger 의 "Non-Stop Mode" 절을 참고한다. GDB 7.0 이전 버전들은 non-stop 모드를 지원하지 않으며, 모든 대상에서 작동하지는 않는다.


gdb-non-stop-setting
변수는 Emacs 가 all-stop 모드 또는 non-stop 모드에서 GDB를 실행하는지를 결정한다. 기본값은
t
인데, non-stop 모드를 이용할 수 있다면 그 사용을 시도함을 의미한다. 값을
nil
로 변경하거나 non-stop 모드를 이용할 수 없을 경우 Emacs는 all-stop 모드에서 GDB를 실행한다. Emacs가 디버깅 세션을 시작하면 변수는 효력을 발휘하고, 사용자가 그 값을 변경하면 어떠한 활성화된 디버깅 세션이든 재시작해야 한다.


쓰레드가 non-stop 모드에서 중지하면 Emacs는 보통 그 쓰레드로 전환한다. 다른 중단된 쓰레드가 이미 선택되었을 때 Emacs 가 이러한 전환을 실행하지 않길 바랄 경우
gdb-switch-when-another-stopped
변수를
nil
로 변경하라.


Emacs는 쓰레드가 중단된 원인에 따라 중단된 쓰레드로 전환 여부를 결정할 수 있다. 쓰레드 전환을 야기시킬 중지 이유를 선택하려면
gdb-switch-reasons
변수를 맞춤화한다.


gdb-stopped-functions
변수는 사용자로 하여금 일부 쓰레드가 중지할 때마다 자신의 함수를 실행하도록 해준다.


Non-stop 모드에서는 GUD 실행 제어 명령어에 대한 여러 모드들 간에 전환이 가능하다.


Non-stop/A

gdb-gud-control-all-threads
t
일 경우 (기본값) 중단(interruption) 및 연속 명령어가 모든 쓰레드에 적용되므로 사용자는
gud-stop-subjob
gud-cont
명령어를 각각 이용하여 모든 쓰레드를 중지 또는 계속할 수 있다. 적어도 하나의 쓰레드가 중지되면 툴바에 '
Go
' 버튼이 표시되는 반면 적어도 하나의 쓰레드가 실행 중이라면 '
Stop
' 버튼이 표시된다.


Non-stop/T

gdb-gud-control-all-threads
nil
이면 현재 쓰레드만 중지/계속된다. GUD 툴바의 '
Go
'와 '
Stop
' 버튼은 현재 쓰레드의 상태에 따라 표시된다.


사용자는 툴바 또는 '
GUD->GDB-MT
' 메뉴에서
gdb-gud-control-all-threads
의 현재 값을 변경할 수 있다.


Stepping 명령어는 항상 현재 쓰레드에 적용된다.


Non-stop 모드에서는 쓰레드를 선택하지 않고 쓰레드를 중단/계속할 수 있다. 쓰레드 버퍼에서 i를 누르면 포인트 아래의 쓰레드를 중단시키고,
c
는 계속하며,
s
는 step through한다. 향후에 그러한 명령어를 더 추가할 수 있다.


사용자가 쓰레드를 중단시키면 '
signal received
' 이유로 중지시킨다. 그 이유가 사용자의
gdb-switch-reasons
(기본값)에 포함되어 있다면 Emacs 는 해당 쓰레드로 전환할 것이다.


Lisp 표현식 실행하기

Emacs는 Lisp의 여러 변형체에 대해 주 모드를 갖고 있다. 그들은 다른 프로그래밍 언어 모드와 동일한 편집 명령어를 사용한다(240 페이지의 23장 [프로그램] 참고). 또한 Lisp 표현식을 실행하기 위한 특수 명령어를 제공한다.


Emacs Lisp 모드

Emacs Lisp 소스 파일을 편집하는 모드다. 현재 최상위 수준의 Lisp 표현식을 평가하도록 C-M-x 를 정의한다. 278 페이지의 24.9절 [Lisp Eval]을 참고한다.


Lisp Interaction 모드

대화형 Emacs Lisp 세션에 사용되는 모드다. 포인트 앞의 표현식을 평가하고 그 값을 버퍼에 삽입하도록 C-j 를 정의한다. 279 페이지의 24.10절 [Lisp 상호작용]을 참고한다.


Lisp 모드

Emacs Lisp가 아닌 Lisps에서 실행되는 프로그램의 소스 파일을 편집하는 데에 사용되는 모드다. 외부 Lisp에서 현재 최상위 수준의 표현식을 평가하도록 C-M-x 를 정의한다. 279 페이지의 24.11절 [외부 Lisp]를 참고한다.


Inferior Lisp 모드

Emacs의 하위프로세스(또는 열위(inferior) 프로세스)로서 실행 중인 외부 Lisp와 함께 대화형 세션에 사용되는 모드다.


Scheme 모드

Lisp 모드와 같지만 Scheme 프로그램에 사용되는 모드다.


Inferior Scheme 모드

Inferior Lisp 모드와 같지만 Scheme에 사용되는 모드다.


Emacs용 Lisp 코드의 라이브러리

Emacs Lisp 코드는 보통
.el
로 끝나는 이름의 파일에 보관된다. 그러한 파일은 Emacs Lisp 모드에서 자동으로 방문된다.


Emacs Lisp 코드는 로딩이 빠르고 공간 차지가 적으며 더 빠르게 실행되는 바이트코드로 컴파일될 수 있다. 관습상 컴파일된 Emacs Lisp 코드는 이름이 '
.elc
' 로 끝나는 별개의 파일로 들어간다. 예를 들어,
foo.el
에 대해 컴파일된 코드는
foo.elc
로 들어간다. Emacs Lisp Reference Manual 의 "Byte Compilation"절을 참고한다.


Emacs Lisp 파일을 로딩하기 위해서는 M-x load-file 을 입력한다. 이 명령어는 미니버퍼를 이용해 파일명을 읽고, 해당 파일의 내용을 Emacs Lisp 코드로서 실행한다. 파일을 먼저 방문할 필요가 없으며, 이 명령어는 기존 Emacs 버퍼가 아니라 디스크로부터 직접 파일을 읽는다.


Emacs Lisp 파일이 Emacs Lisp 로드 경로(아래에 정의)에 설치되면 사용자는 M-x load-file 대신 M-x load-library 를 입력하여 로딩할 수 있다. M-x load-library 명령어는 파일명보다는 라이브러리명의 입력을 요하며, Emacs Lisp 로드 경로에서 각 디렉터리를 검색하면서 해당 라이브러리명에 일치하는 파일을 찾으려 한다. 라이브러리명이 '
foo
' 일 경우
foo.elc
,
foo.el
,
foo
로 명명된 파일을 검색하려 한다. 기본 행위는 처음으로 발견된 파일을 로딩하는 것이다. 이 명령어는
.el
파일보다는
.elc
파일을 선호하는데, 컴파일된 파일이 더 빠르게 로딩되고 실행되기 때문이다.
lib.elc
보다 최신의
lib.el
을 발견하면 누군가
.el
파일에 변경 사항을 적용하고 재컴파일을 잊었을 때를 대비해 경고를 발생시키지만 어쨌든
.elc
파일을 로딩하는건 마찬가지다. (이러한 행위로 인해 사용자는 완료하지 않은 편집을 Emacs Lisp 소스 파일로 저장하고, 변경 내용의 사용이 준비될 때까지 재컴파일하지 않아도 된다.) 하지만
load-prefer-newer
옵션을
nil
이 아닌 값으로 설정하면 Emacs는 위에 설명된 절차보다는 가장 최신 파일 버전을 로딩한다.


Emacs Lisp 프로그램은 주로
load
함수를 이용해 Emacs Lisp 파일을 로딩한다. 이는
load-library
와 비슷하지만 하위수준이고, 추가 인자를 수용한다. the Emacs Lisp Reference Manual 의 "How Programs Do Loading" 절을 참고한다.


Emacs Lisp 로드 경로는
load-path
변수로 정의된다. 그 값은 디렉터리명으로 이루어진 목록(문자열)이어야 한다. 이러한 디렉터리는 M-x load-library 명령어, 하위 수준의
load
함수, 그 외 Emacs Lisp 라이브러리를 검색하는 Emacs 함수에서 명시되는 순으로 검색된다.
load-path
에 목록 엔트리는 현재 기본 디렉터리를 뜻하는 nil이란 특수값을 가질 수도 있지만 이 값을 사용하는 것은 언제건 좋은 생각이 되지 못한다. (
nil
이 목록이 있길 바란다면 M-x load-file 을 사용하길 원하지는 않는지 생각해보길 바란다.)


load-path
의 기본값은 Emacs 에 대한 Lisp 코드가 보관되는 디렉터리의 목록이다. 다른 디렉터리에 고유의 라이브러리를 갖고 있다면 해당 디렉터리를 로드 경로로 추가해도 좋다. 이번 매뉴얼에 설명된 다른 대부분의 변수와 달리
load-path
는 Customize 인터페이스를 통해 변경할 수 없지만 (412 페이지의 33.1절 [간편한 맞춤화] 참고), 다음과 같은 행을 자신의 init 파일에 추가함으로써 디렉터리를 추가할 수는 있다(437 페이지의 33.4절 [Init 파일] 참고):
(add-to-list 'load-path "/path/to/my/lisp/library")


몇몇 명령어들은 자동 로딩되어 사용자가 이러한 명령어를 실행하면 Emacs는 자동으로 그와 관련된 라이브러리를 먼저 로딩한다. 가령 M-x compile 명령어는 (261 페이지의 24.1절 [컴파일] 참고) 자동 로딩되는데, 사용자가 이를 호출하면 Emacs 가
compile
라이브러리를 먼저 자동으로 로딩한다. 반면 M-x recompile 명령어는 자동 로딩되지 않으므로 사용자가
compile
라이브러리를 로딩할 때까진 이용할 수 없다.


자동 로딩은 사용자가 자동 로딩된 명령어의 문서를 검색할 때에도 발생하는데(39 페이지의 7.2절 [이름 도움말] 참고), 문서가 그 라이브러리 내 다른 함수와 변수를 참조할 경우에 그러하다(라이브러리를 로딩하면 Emacs 가
*Help*
버퍼에 하이퍼링크를 적절하게 마련하도록 해준다). 이 기능을 비활성화하려면
help-enable-auto-load
변수를
nil
로 변경하라.


Emacs 는 XEmacs 라는 Emacs 의 수정 버전을 이용해 컴파일된 Lisp 파일의 로딩을 거부하는 것이 기본값인데, 이러한 파일들은 Emacs의 충돌을 야기할 수 있다. 이러한 파일의 로딩을 시도하길 원한다면
load-dangerous-libraries
변수를
t
로 설정한다.


Emacs Lisp 표현식 평가하기

Emacs Lisp 모드는 Emacs Lisp를 편집하기 위한 주 모드이다. 그 모드 명령어는 M-x emacs-lisp-mode 이다.


Emacs는 Emacs Lisp 표현식을 평가하는 명령어를 몇 가지 제공한다. 이러한 명령어를 Emacs Lisp 모드에서 사용하면 Emacs Lisp 코드를 쓰면서 검사할 수 있다. 예를 들어 함수를 다시 쓰고 나면 함수 정의를 평가하여 잇따른 함수 호출에 대해 효력을 발휘하도록 할 수 있다. 이러한 명령어는 전역적으로도 이용 가능하며, Emacs Lisp 모드 밖에서도 이용할 수 있다.


M-:
미니버퍼에서 단일 Emacs Lisp 표현식을 읽고 평가한 후 에코 영역에 값을 출력한다(
eval-expression
).


C-x C-e
포인트 앞에 Emacs Lisp 표현식을 평가하고 에코 영역에 값을 출력한다(
eval-last-sexp
).


C-M-x
(Emacs Lisp 모드에서)
M-x eval-defun
포인트를 포함하거나 포인트 뒤에 defun 을 평가하고 에코 영역에 값을 출력한다(
eval-defun
).


M-x eval-region
영역 내 모든 Emacs Lisp 표현식을 평가한다.


M-x eval-buffer
버퍼 내 모든 Emacs Lisp 표현식을 평가한다.


M-: (
eval-expression
)은 미니버퍼를 이용해 표현식을 읽고 평가한다. (표현식을 평가하기 전에 현재 버퍼는 사용자가 표현식을 입력한 미니버퍼가 아니라 M-: 를 입력할 당시 현재 버퍼였던 버퍼로 전환된다.)


C-x C-e (
eval-last-sexp
) 명령어는 버퍼에서 포인트 앞에 선행하는 Emacs Lisp 표현식을 평가하고, 에코 영역에 값을 표시한다. 평가 결과가 정수이면 다른 포맷(8진수, 16진수, 문자)의 값과 함께 표시된다.


M-: 또는 C-x C-e 에 접두 인자가 주어지면 값은 에코 영역이 아니라 현재 버퍼에 포인트 위치로 삽입한다. 접두 인자가 0이면 어떤 정수 출력 값이든 다른 포맷으로 표현된 값(8진수, 16진수, 문자)과 함께 삽입된다. 그러한 접두 인자는
eval-expression-print-level
eval-expression-print-length
변수에 따라 출력 값의 약어를 금한다(아래 참고).


eval-defun
명령어는 Emacs Lisp 코드에서 C-M-x 에 바인딩되어 있다. 이는 포인트를 포함하거나 뒤에 따르는 최상위 수준 Lisp 표현식을 평가하고, 값을 에코 영역에 출력한다. 이 컨텍스트에서 최상위 수준의 표현식을 "defun" 이라 부르지만 실제
defun
(함수 정의)일 필요는 없다. 특히 이 명령어는
defvar
표현식을 특별하게 취급한다. 보통은 defvar 표현식을 평가하면 그것이 정의하는 변수에 이미 값이 있을 경우 아무 일도 수행하지 않는다. 하지만 이 명령어는
defvar
가 명시한 초기 값으로 변수를 무조건 리셋하는데, 이는 Emacs Lisp 프로그램을 디버깅하는 데에 편리하다.
defcustom
deface
표현식은 비슷하게 취급된다. 이번 절에 설명된 그 외 명령어들은 이러한 특별한 기능이 없음을 주목한다.


C-M-x 는 접두 인자를 이용해 Edebug에 대한 함수 정의, Emacs Lisp Debugger를 다룬다. the Emacs Lisp Reference Manual 의 "Instrumenting" 절을 참고한다.


M-x eval-region 명령어는 영역의 텍스트를 하나 또는 이상의 Lisp 표현식으로서 파싱하고 하나씩 평가한다. M-x eval-buffer 도 비슷하지만 전체 버퍼를 평가한다는 차이가 있다.


eval-expression-print-level
eval-expression-print-length
옵션은 평가 명령어를 줄여 쓰기 전에 그 결과에 출력할 목록의 최대 길이와 깊이를 제어한다.
eval-expression
또는
eval-last-sexp
에 접두 인자 0 을 제공하면 목록이 전체적으로 출력된다.
eval-expression-debug-on-error
는 이러한 명령어가 사용될 때 평가 오류가 디버거를 호출할 것인지 여부를 통제하는데, 기본값은 t이다.


Lisp 상호작용 버퍼

Emacs 가 시작될 때는 Emacs Lisp 표현식을 대화형으로 평가하기 위해 제공되는
*scratch*
라는 버퍼를 포함한다. 그 주 모드는 Lisp Interaction 모드이다. M-x lisp-interaction-mode 를 입력하면 Lisp Interaction 모드를 활성화할 수도 있다.


*scratch*
버퍼와 그 외 다른 Lisp Interaction 모드 버퍼에서 C-j (
eval-print-last-sexp
)를 실행하면 포인트 앞에 Lisp 표현식을 평가하고 값을 포인트에 삽입한다. 따라서 사용자가 버퍼에 표현식을 입력한 후 각 표현식 다음에 C-j 를 입력하면 버퍼는 평가된 표현식과 그 값의 트랜스크립트를 기록한다. Lisp Interaction 모드에서 그 외 다른 명령어들은 모두 Emacs Lisp 모드와 동일하다.


시작 시
*scratch*
버퍼는 Lisp 주석 형태로 된 짧은 메시지를 포함하는데, 이는 버퍼의 용도가 무엇인지를 설명한다. 이 메시지는
initial-scratch-message
변수로 제어되고, 그 값은 문자열이나 nil(메시지를 금함을 의미)이 가능하다.


Emacs Lisp 표현식을 대화형으로 평가하는 또 다른 방법은 Emacs Lisp 표현식을 평가하기 위해 Shell 모드에 가까운 인터페이스를 제공하는 Inferior Emacs Lisp 모드를 사용하는 방법이다(385 페이지의 31.4.3절 [셸 모드] 참고). M-x ielm 을 입력하여 이 모드를 사용하는
*ielm*
버퍼를 생성한다. 상세한 정보는 해당 명령어의 문서를 참고한다.


외부 Lisp 실행하기

Lisp 모드는 Common Lisp 처럼 다용도 Lisp dialects 로 쓰여진 프로그램을 편집하는 주 모드이다. 모드 명령어는 M-x lisp-mode 이다. Emacs 는
.l
,
.lsp
,
.lisp
로 끝나는 이름을 가진 파일에 대해 자동으로 Lisp 모드를 사용한다.


사용자는 Emacs 의 하위프로세스 또는 열위 프로세스(inferior process)로서 외부 Lisp 세션을 실행하여 표현식을 평가하도록 해당 세션으로 전달할 수 있다. 외부 Lisp 세션을 시작하려면 M-x run-lisp 를 실행한다. 그러면
lisp
이라는 프로그램이 실행되어 입력과 출력이
*inferior-lisp*
라는 Emacs 버퍼를 통과하도록 준비한다. M-x run-lisp 에 의해 실행되는 Lisp 프로그램의 이름을 변경하려면
inferior-lisp-program
변수를 변경하라.


*lisp*
버퍼에 대한 주 모드는 Inferior Lisp 모드로, Lisp 모드와 Shell 모드의 특징을 결합한 것이다(385 페이지의 31.4.3절 [셸 모드] 참고). Lisp 세션으로 입력을 전송하려면
*lisp*
버퍼 끝으로 가서 입력 값을 타이핑한 다음 RET 을 입력한다. Lisp 세션으로부터 터미널 출력은 자동으로 버퍼에 삽입된다.


Lisp 모드에서 Lisp 프로그램을 편집할 때 Lisp 모드 버퍼로부터 M-x run-lisp 를 이용해 시작된 Lisp 세션으로 표현식을 전송하려면 C-M-x (
lisp-eval-defun
)을 입력하면 된다. 전송되는 표현식은 포인트에 위치하거나 포인트 뒤에 따라오는 최상위 수준의 Lisp 표현식이다. 그 결과 값은 평소대로
*inferior-lisp*
버퍼로 들어간다. 따라서 Lisp 모드에서 C-M-x 의 효과는 Emacs Lisp 모드에서의 효과와 매우 비슷한데(278 페이지의 24.9절 [Lisp Eval] 참고), 표현식이 Emacs에서 평가되는 대신 다른 Lisp 환경으로 전송된다는 점은 다르다.


Scheme 코드를 편집하고 표현식을 Scheme 하위프로세스로 전송하는 기능은 매우 비슷하다. Scheme 소스 파일은 Scheme 모드에서 편집되는데, 이는 M-x scheme-mode 를 이용해 직접 활성화 가능하다. M-x run-scheme 을 입력하여 Scheme 세션을 시작하고 (
*scheme*
으로 명명된 Scheme과 상호작용하기 위한 버퍼) C-M-x 를 입력하여 그 세션으로 표현식을 전송할 수 있다.


Notes