aarch64-linux-gnu용 Valgrind 3.21.0 크로스 컴파일指南

개발 환경 구성

본 문서에서는 ARM64(64비트 ARM) 보드에서 동작하는 메모리 분석 도구인 Valgrind를 x86_64 호스트에서 크로스 컴파일하는 방법을 설명한다.

빌드 환경

  • 호스트 PC: Ubuntu Server 22 LTS
  • 타겟 보드: ARM64(AArch64) 아키텍처

크로스 컴파일 도구체인

Linaro에서 제공하는 GCC 크로스 컴파일러를 사용한다:

https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/aarch64-linux-gnu/

참고사항: GCC 7.5 이상을 사용하려면 ARM 공식 사이트(https://developer.arm.com/downloads/-/gnu-a)에서 도구체인을 다운로드해야 한다.

도구체인을 선택할 때 다음 사항을 확인해야 한다:

  • GCC 버전이 타겟 보드의 glibc 버전과 호환되어야 함
  • 아키텍처(aarch64-linux-gnu)가 타겟 운영체제 및 SOC 코어와 일치해야 함

소스코드 준비

Valgrind 소스코드는 공식 웹사이트에서 다운로드한다:

https://valgrind.org/downloads/current.html

빌드 전에 필요한 의존 패키지를 설치한다:

sudo apt install automake
sudo apt install libc6-dbg

컴파일 스크립트 작성

Valgrind 3.21.0 소스코드의 README.aarch64 파일에 상세한 빌드 안내가 포함되어 있다. 이를 참고하여 스크립트를 작성한다.

#!/bin/sh

export CROSS_PREFIX=/your_path_to_linaro/bin/aarch64-linux-gnu-

export CC=${CROSS_PREFIX}gcc
export LD=${CROSS_PREFIX}ld
export AR=${CROSS_PREFIX}ar

./autogen.sh
./configure --prefix=`pwd`/Install --host=aarch64-unknown-linux \
            --enable-only64bit
make -j4
make -j4 install

tar -czf ../valgrind-3.21.0-aarch64.tar.gz Install/
echo "빌드 완료: ../valgrind-3.21.0-aarch64.tar.gz"

위 스크립트에서 CROSS_PREFIX를 실제 크로스 컴파일 도구체인 경로로 수정해야 한다. 즉, aarch64-linux-gnu-gcc가 위치한 디렉토리의 경로를 지정하면 된다.

빌드가 완료되면 상위 디렉토리에 valgrind-3.21.0-aarch64.tar.gz 파일이 생성된다.

타겟 보드への部署

빌드된 패키지를 ARM64 보드로 전송하고 압축을 해제한다:

tar -xvf valgrind-3.21.0-aarch64.tar.gz
chmod -R +x Install/ && cp Install/* / -rfv
export VALGRIND_LIB=/libexec/valgrind/

메모리 분석 기능을 완전히 활용하려면 디버그 정보가 포함된 동적 링크러(libc-debug 버전)를 보드에 복사해야 한다. 이 과정은 아래의 오류 해결 섹션에서 다룬다.

使用법

기본 실행 명령어

valgrind --tool=memcheck --leak-check=full <분석할 프로그램> [인수]
valgrind --tool=memcheck --leak-check=full ./myapp

분석 대상 프로그램이 디버그 정보(-g 옵션)로 컴파일되어 있다면, 메모리 누수 및 오류를 상세히 확인할 수 있다.

常见 오류 및 해결 방법

1. memcheck 도구 로드 실패

오류 메시지:

valgrind: failed to start tool 'memcheck' for platform 'arm64-linux': No such file or directory

해결 방법: VALGRIND_LIB 환경변수를 설정한다.

export VALGRIND_LIB=/libexec/valgrind/

~/.bashrc에 위 줄을 추가하면 영구적으로 적용된다.

2. 함수 리다이렉션 설정 오류

이 오류는 타겟 보드에 디버그 정보가 없는 동적 링크러가 있을 때 발생한다. 프로그램이 완전히 디버그 정보로 컴파일되지 않았거나, 디버그 심볼이 포함된 libc가 보드에 없으면 이 문제가 발생한다.

오류 메시지:

root@plnx:/tmp# export VALGRIND_LIB=/libexec/valgrind/ && valgrind --tool=memcheck --leak-check=full /run/my_exec
==7643== Memcheck, a memory error detector
==7643== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==7643== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==7643== Command: /run/my_exec
==7643==

valgrind:  Fatal error at startup: a function redirection
valgrind:  which is mandatory for this platform-tool combination
valgrind:  cannot be set up.  Details of the redirection are:
valgrind:
valgrind:  A must-be-redirected function
valgrind:  whose name matches the pattern:      strlen
valgrind:  in an object with soname matching:   ld-linux-aarch64.so.1
valgrind:  was not found whilst processing
valgrind:  symbols from the object with soname: ld-linux-aarch64.so.1
valgrind:
valgrind:  Possible fixes: (1, short term): install glibc's debuginfo
valgrind:  package on this machine.  (2, longer term): ask the packagers
valgrind:  for your Linux distribution to please in future ship a non-
valgrind:  stripped ld.so (or whatever the dynamic linker .so is called)
valgrind:  that exports the above-named function using the standard
valgrind:  calling conventions for this platform.  The package you need
valgrind:  to install for fix (1) is called
valgrind:
valgrind:    On Debian, Ubuntu:                 libc6-dbg
valgrind:    On SuSE, openSuSE, Fedora, RHEL:   glibc-debuginfo
valgrind:
valgrind:  Note that if you are debugging a 32 bit process on a
valgrind:  64 bit system, you will need a corresponding 32 bit debuginfo
valgrind:  package (e.g. libc6-dbg:i386).
valgrind:
valgrind:  Cannot continue -- exiting now.  Sorry.
해결 절차

먼저 호스트 PC의 크로스 컴파일 도구체인에서 디버그 심볼이 포함된 동적 링크러를 찾는다:

$ find ./aarch64-linux-gnu -name "*ld*.so"
./aarch64-linux-gnu/libc/lib/ld-2.25.so

$ file ./aarch64-linux-gnu/libc/lib/ld-2.25.so
./aarch64-linux-gnu/libc/lib/ld-2.25.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=73b23c16ff9fe3eab046636cd9dd6db9d3309f27, with debug_info, not stripped

검색된 ld-2.25.so 파일을 타겟 보드로 전송하고 실행 권한을 부여한 후, Valgrind와 함께 사용한다:

chmod +x /tmp/ld-2.25.so
export VALGRIND_LIB=/libexec/valgrind/ && valgrind --tool=memcheck --leak-check=full /tmp/ld-2.25.so /run/my_exec

실행 결과 예시

root@plnx:/tmp# export VALGRIND_LIB=/libexec/valgrind && valgrind --tool=memcheck --leak-check=full /tmp/ld-2.25.so /run/my_exec
==27913== Memcheck, a memory error detector
==27913== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==27913== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==27913== Command: /tmp/ld-2.25.so /run/my_exec
==27913==

Hello World!
***************************************************************************

==27913==
==27913== HEAP SUMMARY:
==27913==     in use at exit: 0 bytes in 0 blocks
==27913==   total heap usage: 33 allocs, 33 frees, 90,118 bytes allocated
==27913==
==27913== All heap blocks were freed -- no leaks are possible
==27913==
==27913== For lists of detected and suppressed errors, rerun with: -s
==27913== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

위 결과에서 "All heap blocks were freed -- no leaks are possible"를 확인함으로써 메모리 누수가 없음을 검증할 수 있다.

편의 스크립트 작성

길어진 명령어를 간단하게 만들기 위해 래퍼 스크립트를 만든다:

#!/bin/sh

# tar -xvf valgrind-3.21.0-aarch64.tar.gz && chmod -R +x Install/ && cp Install/* / -rfv
# chmod +x /tmp/ld-*.so

export VALGRIND_LIB=/libexec/valgrind && valgrind --tool=memcheck --leak-check=full /tmp/ld-2.25.so $@

이 스크립트를 run_memcheck.sh로 저장하고 실행 권한을 부여한다.

사용 예시

# 일반 실행
./myapp 1 0

# 메모리 분석 실행
./run_memcheck.sh ./myapp 1 0

디버그 심볼이 포함된 동적 링크러를 /tmp 디렉토리에 두는 이유는 디버깅 시에만 임시로 사용하기 때문이다. 제품 환경에서는 디버그 정보가 포함된 바이너리를 사용하지 않는 것이 일반적이다.

부록: 특수 변수 설명

$@ 와 $* 의 차이점:

  • $*: 모든 인수를 하나의 문자열로 결합 ("$1 $2 ... $n")
  • $@: 각 인수를 개별적인 문자열로 유지 ("$1" "$2" ... "$n")

태그: valgrind cross-compilation aarch64 arm64 embedded-systems

7월 5일 21:39에 게시됨