Linux Uprobe란? 사용자 공간(User Space) 함수까지 추적하는 eBPF 동적 분석 기술 완벽 이해

Linux에서 성능 분석이나 장애 원인을 파악할 때는 커널 함수뿐 아니라 사용자 공간(User Space) 에서 실행되는 함수도 분석해야 하는 경우가 많습니다. 예를 들어 Nginx, MySQL, Redis, Java 애플리케이션 등이 느려졌다면 커널이 아니라 애플리케이션 내부 함수에서 병목이 발생했을 가능성이 있습니다.

이때 사용하는 기술이 Uprobe(User Probe) 입니다.

Uprobe는 사용자 공간 프로그램의 함수에 동적으로 Probe를 삽입하여 실행 흐름을 추적하는 Linux Kernel 기능입니다. Kprobe가 커널 함수를 추적한다면, Uprobe는 일반 애플리케이션의 함수를 추적하는 역할을 합니다.

이번 글에서는 Uprobe의 개념과 동작 원리, Kprobe와의 차이점, eBPF 활용 방법, 그리고 실무 활용 사례를 자세히 알아보겠습니다.

Linux Uprobe란?

Uprobe는 실행 중인 사용자 공간 프로그램의 함수 호출을 추적하는 동적 계측(Dynamic Instrumentation) 기능입니다.

동작 구조는 다음과 같습니다.

Application

↓

User Function

↓

Uprobe

↓

eBPF Program

↓

데이터 수집

프로그램을 수정하거나 재컴파일하지 않아도 함수 호출을 분석할 수 있습니다.

Uprobe가 필요한 이유

예를 들어 다음과 같은 상황을 생각해 보겠습니다.

  • MySQL 응답 속도 저하
  • Redis 명령 처리 지연
  • Java API 성능 저하
  • Python 애플리케이션 병목

Kernel에는 문제가 없지만 애플리케이션 내부 함수가 느릴 수 있습니다.

Uprobe를 사용하면

  • 함수 호출 횟수
  • 실행 시간
  • 전달된 인자
  • 반환값

등을 실시간으로 확인할 수 있습니다.

Uprobe의 동작 원리

전체 흐름은 다음과 같습니다.

Application 실행

↓

특정 함수 호출

↓

Uprobe 실행

↓

eBPF Program

↓

데이터 저장

↓

User Space 분석

Kernel은 사용자 프로그램의 특정 함수 진입 시점에서 Probe를 실행합니다.

Uretprobe란?

Uprobe는 함수 시작 시점을 추적합니다.

반면 Uretprobe(User Return Probe) 는 함수 종료 시점을 추적합니다.

Function Start

↓

Uprobe

↓

Function 실행

↓

Return

↓

Uretprobe

이를 통해 함수 실행 시간과 반환값도 분석할 수 있습니다.

Uprobe와 Kprobe의 차이

항목UprobeKprobe
대상User Space 함수Kernel 함수
분석 대상애플리케이션Linux Kernel
활용프로그램 성능 분석Kernel 디버깅
대표 대상Nginx, MySQL, RedisScheduler, Memory, Network

두 기술은 함께 사용하는 경우가 많습니다.

추적 가능한 프로그램

대표적으로 다음과 같은 프로그램을 추적할 수 있습니다.

  • nginx
  • apache
  • mysql
  • redis-server
  • postgres
  • python
  • java
  • node
  • php-fpm

사용자 공간에서 실행되는 대부분의 ELF 실행 파일을 대상으로 사용할 수 있습니다.

함수 심볼(Symbol) 확인

Uprobe를 사용하려면 함수 이름을 알아야 합니다.

다음 명령으로 심볼을 확인할 수 있습니다.

nm /usr/sbin/nginx

또는

objdump -t /usr/sbin/nginx

동적 라이브러리의 경우

nm -D /lib/x86_64-linux-gnu/libc.so.6

함수 이름과 주소를 확인할 수 있습니다.

bpftrace에서 Uprobe 사용

예를 들어 malloc() 함수 호출을 추적하려면

sudo bpftrace -e '
uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc
{
    printf("malloc\n");
}'

메모리 할당 함수가 호출될 때마다 출력됩니다.

Uretprobe 예제

함수 종료 시점 추적

sudo bpftrace -e '
uretprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc
{
    printf("malloc finished\n");
}'

함수 실행이 끝날 때마다 이벤트를 확인할 수 있습니다.

호출 횟수 집계

함수 호출 빈도를 계산할 수도 있습니다.

sudo bpftrace -e '
uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc
{
    @count++;
}'

종료하면

@count: 25480

처럼 호출 횟수를 확인할 수 있습니다.

실행 시간 분석

Uprobe와 Uretprobe를 함께 사용하면 함수 실행 시간을 측정할 수 있습니다.

Uprobe

↓

Start Time 저장

↓

Function 실행

↓

Uretprobe

↓

End Time 계산

↓

실행 시간 출력

느린 함수나 병목 구간을 찾는 데 매우 유용합니다.

bpftool 확인

현재 로드된 eBPF 프로그램 확인

sudo bpftool prog show

맵 확인

sudo bpftool map show

현재 실행 중인 eBPF 객체를 확인할 수 있습니다.

실무에서 자주 사용하는 명령어

함수 심볼 확인

nm -D /lib/x86_64-linux-gnu/libc.so.6

프로그램 심볼 확인

objdump -t /usr/sbin/nginx

eBPF 프로그램 확인

sudo bpftool prog show

Map 확인

sudo bpftool map show

bpftrace 실행

sudo bpftrace

Kernel 버전

uname -r

실무 사례

예를 들어 운영 중인 Nginx 서버에서 응답 시간이 갑자기 증가했다고 가정해 보겠습니다.

다음과 같은 절차로 분석할 수 있습니다.

  1. Nginx 실행 파일의 심볼 확인
  2. 요청 처리 함수에 Uprobe 연결
  3. Uretprobe로 실행 시간 측정
  4. eBPF Map에 통계 저장
  5. 느린 함수 확인
  6. 병목 원인 분석 후 최적화

Kernel에는 문제가 없는데 애플리케이션 내부에서 병목이 발생하는 경우 매우 효과적인 분석 방법입니다.

자주 묻는 질문

Uprobe는 어떤 프로그램에 사용할 수 있나요?

ELF 형식으로 빌드된 대부분의 사용자 공간 프로그램에 적용할 수 있습니다. 단, 심볼 정보가 제거(Strip)된 실행 파일은 함수 이름을 찾기 어려울 수 있습니다.

Uprobe와 Uretprobe를 함께 사용하는 이유는 무엇인가요?

Uprobe는 함수 시작 시점을, Uretprobe는 종료 시점을 추적합니다. 두 기능을 함께 사용하면 함수 실행 시간과 반환값을 분석할 수 있어 성능 최적화에 매우 유용합니다.

Uprobe는 운영 서버에서도 사용할 수 있나요?

가능합니다. 필요한 함수만 선택적으로 추적하면 성능 영향이 크지 않아 운영 환경에서도 성능 분석과 장애 원인 파악에 널리 활용됩니다.

마무리

Linux Uprobe는 사용자 공간 프로그램의 함수를 동적으로 추적하는 강력한 분석 기술입니다. Kprobe가 커널 함수를 분석한다면, Uprobe는 Nginx, MySQL, Redis, Java, Python 등 애플리케이션 내부 동작을 세밀하게 관찰할 수 있습니다. eBPF, bpftrace, bpftool과 함께 활용하면 운영 중인 서비스의 병목 원인을 효과적으로 분석하고 성능을 최적화할 수 있습니다.

댓글 남기기