이기종간의 환경에서 GDB 를 이용해서 디버깅하는 방법에 대해 설명하고 있다.
여기서 이기종이라는 것는 타겟(ARM)과 호스트(X86)가 다른 아키텍처일 경우를 뜻한다. 하지만, 여기서 다루는 내용은 타겟과 호스트가 같은 경우에도 적용이 가능하다. 실제로 타겟(X86)과 호스트(X86) 인 경우에도 잘 동작했었다.

준비운동하기

본격적인 시작에 앞서, 여기서는 X86 의 호스트에 Xscale 타겟을 이용할 것이다. 환경은 다음과 같다.

호스트 타겟(휴인스 PXA255-PRO3)
아키텍처 X86 Xscale
OS Redhat 9 Linux
커널 2.4.18 2.4.19
GDB 6.5 6.5
IP 주소 192.168.0.1 192.168.0.2
ETC 크로스케이블(LAN) 툴체인(휴인스제공)

표에서 보듯이 가장 중요한 GDB 의 경우, 2006년 11월 9일 현재 가장 최신버전을 사용했다.
http://www.gnu.org/software/gdb/download/ 에서 다운로드 할 수 있다.

호스트 설정

먼저 호스트쪽 부터 보도록 한다.

#tar xzf gdb-6.5.tar.gz
#cd gdb-6.5
#./configure -target=arm-linux --prefix=/usr/local/arm-dev -v
#make
#make install

GDB 의 경우, 컴파일시에 현재 부팅한 커널의 소스를 참조한다. 그래서 만일 /usr/src 아래에 커널 소스가 없으면, 컴파일 시에 오류가 발생할 것이다. 이때에는 현재 부팅한 커널의 소스의 링크를 걸던지, 아니면, 따로 커널 컴파일을 해서 링크를 걸어야 한다.

#cd /usr/src/
#ln -s linux-2.4.20-8 linux
#ln -s linux-2.4.20-8 linux-2.4

구체적인 방법은 위와 같다.
오류없이 설치되었다면, 설치된 경로의 bin 디렉토리에 가면, 'arm-linux-gdb' 파일이 생성되었을 것이다.

타겟 설정

호스트 설정에 비하면 타겟 설정은 좀더 복잡하다고 하겠다. 앞에서의 과정이 호스트에서 사용할 'arm-linux-gdb' 파일을 생성했다고 한다면, 여기서는 타겟에서 사용할 'gdbserver' 를 생성해야 한다. 물론 타겟에서 사용할 것이기 때문에, 크로스 컴파일러를 사용해서 컴파일해야 한다.
초반에서 언급한대로, 여기서는 휴인스에서 제공하는 크로스 컴파일러를 사용했다.
이에 대한 설치 방법은 생략하겠다.

#cd gdb-6.5
#cd gdb/gdbserver
#export CC=arm-linux-gcc
#./configure --target=arm-linux --host=arm-linux
#make

앞에서의 호스트 설정에서 컴파일 했던 GDB 소스 디렉토리를 그대로 사용한다. 오류없이 컴파일 되었다면, 'gdbserver' 이 생성되었을 것이다.
이 파일을 이제 타겟보드에 올려야 한다. 다음은 타겟에서 실행한 모습이다.

# ./gdbserver
Usage:  gdbserver COMM PROG [ARGS ...]
        gdbserver COMM --attach PID
 
COMM may either be a tty device (for serial debugging), or
HOST:PORT to listen for a TCP connection.

이제 디버깅할 모든 준비가 끝났다.

디버깅 하기

다음은 디버깅에 사용할 예제 소스이다.

#include <stdio.h>
 
int add(int a, int b);
int sub(int a, int b);
 
int main()
{
	int x=0;
	int y=0;
	printf("start!!!\n");
	x = add(3,2);
	printf("X is %d\n", x);
	y = sub(4,2);
	printf("Y is %d\n", y);
	return 0;
}
 
int add(int a, int b)
{
	int c=0;
	c = a+b;
	return c;
}
 
int sub(int a, int b)
{
	int c=0;
	c = a-b;
	return c;
}

디버깅 할 수 있도록 다음과 같이 컴파일한다.

#arm-linux-gcc -g -o test test.c

디버깅의 최종적인 구성을 보자면, 아래와 같다.

호스트 arm-linux-gdb, test(arm object)
타겟 gdbserver, test(arm object)

이기종의 디버깅은 LAN 을 통해서 이루어진다. 동작 순서는 다음과 같다.

  1. 타겟에서 gdbserver 를 이용해서 디버깅 할 프로그램과 특정 포트를 open 시킨다. (ex : 8181)
  2. 호스트에서 디버깅할 프로그램을 이용해서 gdb 를 구동시킨다. 호스트에서 디버깅할 프로그램이 필요한 것은 심볼 테이블을 읽어들이기 위함이다.
  3. 호스트에서 타겟의 지정된 포트에 접속한다.
  4. Breakpoint 를 지정하고, 'c' 명령어를 이용해서 디버깅을 한다.
#./gdbserver 192.168.0.2:8181 test
Process test created; pid = 83
Listening on port 8181
#./arm-linux-gdb test
(gdb) target remote 192.168.0.2:8181
(gdb) b main
(gdb) c
  • computer/rtcclab/gdb_사용하기_-_3.이기종_디버깅.txt
  • Last modified: 3 years ago
  • by likewind