← Documents Documentation/trace/uprobetracer.rst GitHub 원문 ↗

Linux 6.18.37 · Tracing

Uprobe 추적기: Uprobe 기반 이벤트 추적

사용자 공간 실행 파일과 라이브러리에 uprobe/uretprobe를 등록하고 fetch 인수, 객체 오프셋, 이벤트 format과 trace 출력을 해석하는 방법을 설명합니다.

Source pathDocumentation/trace/uprobetracer.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

uprobetracer.rst:1-186

uprobe는 사용자 공간 객체의 파일 오프셋에 동적 trace 이벤트를 설치합니다. 객체 기준 오프셋을 정확히 계산하고, 프로브 등록과 이벤트 활성화를 구분하며, fetch 인수의 자료형과 반환 프로브 제약을 지키는 것이 핵심입니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 =========================================
2 Uprobe-tracer: Uprobe-based Event Tracing
3 =========================================
4
5 :Author: Srikar Dronamraju
6
7
8 Overview
9 --------
10 Uprobe based trace events are similar to kprobe based trace events.
11 To enable this feature, build your kernel with CONFIG_UPROBE_EVENTS=y.
12
13 Similar to the kprobe-event tracer, this doesn't need to be activated via
14 current_tracer. Instead of that, add probe points via
15 /sys/kernel/tracing/uprobe_events, and enable it via
16 /sys/kernel/tracing/events/uprobes/<EVENT>/enable.
17
18 However unlike kprobe-event tracer, the uprobe event interface expects the
19 user to calculate the offset of the probepoint in the object.
20
21 You can also use /sys/kernel/tracing/dynamic_events instead of
22 uprobe_events. That interface will provide unified access to other
23 dynamic events too.
24
25 Synopsis of uprobe_tracer
26 -------------------------
27 ::
28
29 p[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS] : Set a uprobe
30 r[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe)
31 p[:[GRP/][EVENT]] PATH:OFFSET%return [FETCHARGS] : Set a return uprobe (uretprobe)
32 -:[GRP/][EVENT] : Clear uprobe or uretprobe event
33
34 GRP : Group name. If omitted, "uprobes" is the default value.
35 EVENT : Event name. If omitted, the event name is generated based
36 on PATH+OFFSET.
37 PATH : Path to an executable or a library.
38 OFFSET : Offset where the probe is inserted.
39 OFFSET%return : Offset where the return probe is inserted.
40
41 FETCHARGS : Arguments. Each probe can have up to 128 args.
42 %REG : Fetch register REG
43 @ADDR : Fetch memory at ADDR (ADDR should be in userspace)
44 @+OFFSET : Fetch memory at OFFSET (OFFSET from same file as PATH)
45 $stackN : Fetch Nth entry of stack (N >= 0)
46 $stack : Fetch stack address.
47 $retval : Fetch return value.(\*1)
48 $comm : Fetch current task comm.
49 +|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*2)(\*3)
50 \IMM : Store an immediate value to the argument.
51 NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
52 FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
53 (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
54 (x8/x16/x32/x64), "string" and bitfield are supported.
55
56 (\*1) only for return probe.
57 (\*2) this is useful for fetching a field of data structures.
58 (\*3) Unlike kprobe event, "u" prefix will just be ignored, because uprobe
59 events can access only user-space memory.
60
61 Types
62 -----
63 Several types are supported for fetch-args. Uprobe tracer will access memory
64 by given type. Prefix 's' and 'u' means those types are signed and unsigned
65 respectively. 'x' prefix implies it is unsigned. Traced arguments are shown
66 in decimal ('s' and 'u') or hexadecimal ('x'). Without type casting, 'x32'
67 or 'x64' is used depends on the architecture (e.g. x86-32 uses x32, and
68 x86-64 uses x64).
69 String type is a special type, which fetches a "null-terminated" string from
70 user space.
71 Bitfield is another special type, which takes 3 parameters, bit-width, bit-
72 offset, and container-size (usually 32). The syntax is::
73
74 b<bit-width>@<bit-offset>/<container-size>
75
76 For $comm, the default type is "string"; any other type is invalid.
77
78
79 Event Profiling
80 ---------------
81 You can check the total number of probe hits per event via
82 /sys/kernel/tracing/uprobe_profile. The first column is the filename,
83 the second is the event name, the third is the number of probe hits.
84
85 Usage examples
86 --------------
87 * Add a probe as a new uprobe event, write a new definition to uprobe_events
88 as below (sets a uprobe at an offset of 0x4245c0 in the executable /bin/bash)::
89
90 echo 'p /bin/bash:0x4245c0' > /sys/kernel/tracing/uprobe_events
91
92 * Add a probe as a new uretprobe event::
93
94 echo 'r /bin/bash:0x4245c0' > /sys/kernel/tracing/uprobe_events
95
96 * Unset registered event::
97
98 echo '-:p_bash_0x4245c0' >> /sys/kernel/tracing/uprobe_events
99
100 * Print out the events that are registered::
101
102 cat /sys/kernel/tracing/uprobe_events
103
104 * Clear all events::
105
106 echo > /sys/kernel/tracing/uprobe_events
107
108 Following example shows how to dump the instruction pointer and %ax register
109 at the probed text address. Probe zfree function in /bin/zsh::
110
111 # cd /sys/kernel/tracing/
112 # cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp
113 00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh
114 # objdump -T /bin/zsh | grep -w zfree
115 0000000000446420 g DF .text 0000000000000012 Base zfree
116
117 0x46420 is the offset of zfree in object /bin/zsh that is loaded at
118 0x00400000. Hence the command to uprobe would be::
119
120 # echo 'p:zfree_entry /bin/zsh:0x46420 %ip %ax' > uprobe_events
121
122 And the same for the uretprobe would be::
123
124 # echo 'r:zfree_exit /bin/zsh:0x46420 %ip %ax' >> uprobe_events
125
126 .. note:: User has to explicitly calculate the offset of the probe-point
127 in the object.
128
129 We can see the events that are registered by looking at the uprobe_events file.
130 ::
131
132 # cat uprobe_events
133 p:uprobes/zfree_entry /bin/zsh:0x00046420 arg1=%ip arg2=%ax
134 r:uprobes/zfree_exit /bin/zsh:0x00046420 arg1=%ip arg2=%ax
135
136 Format of events can be seen by viewing the file events/uprobes/zfree_entry/format.
137 ::
138
139 # cat events/uprobes/zfree_entry/format
140 name: zfree_entry
141 ID: 922
142 format:
143 field:unsigned short common_type; offset:0; size:2; signed:0;
144 field:unsigned char common_flags; offset:2; size:1; signed:0;
145 field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
146 field:int common_pid; offset:4; size:4; signed:1;
147 field:int common_padding; offset:8; size:4; signed:1;
148
149 field:unsigned long __probe_ip; offset:12; size:4; signed:0;
150 field:u32 arg1; offset:16; size:4; signed:0;
151 field:u32 arg2; offset:20; size:4; signed:0;
152
153 print fmt: "(%lx) arg1=%lx arg2=%lx", REC->__probe_ip, REC->arg1, REC->arg2
154
155 Right after definition, each event is disabled by default. For tracing these
156 events, you need to enable it by::
157
158 # echo 1 > events/uprobes/enable
159
160 Lets start tracing, sleep for some time and stop tracing.
161 ::
162
163 # echo 1 > tracing_on
164 # sleep 20
165 # echo 0 > tracing_on
166
167 Also, you can disable the event by::
168
169 # echo 0 > events/uprobes/enable
170
171 And you can see the traced information via /sys/kernel/tracing/trace.
172 ::
173
174 # cat trace
175 # tracer: nop
176 #
177 # TASK-PID CPU# TIMESTAMP FUNCTION
178 # | | | | |
179 zsh-24842 [006] 258544.995456: zfree_entry: (0x446420) arg1=446420 arg2=79
180 zsh-24842 [007] 258545.000270: zfree_exit: (0x446540 <- 0x446420) arg1=446540 arg2=0
181 zsh-24842 [002] 258545.043929: zfree_entry: (0x446420) arg1=446420 arg2=79
182 zsh-24842 [004] 258547.046129: zfree_exit: (0x446540 <- 0x446420) arg1=446540 arg2=0
183
184 Output shows us uprobe was triggered for a pid 24842 with ip being 0x446420
185 and contents of ax register being 79. And uretprobe was triggered with ip at
186 0x446540 with counterpart function entry at 0x446420.
187

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

개요와 활성화 경로

1-24

저자는 Srikar Dronamraju입니다. uprobe 기반 추적 이벤트는 kprobe 기반 추적 이벤트와 비슷하지만, 실행 파일이나 공유 라이브러리 같은 사용자 공간 객체의 명령 위치를 대상으로 합니다.

이 기능을 사용하려면 커널을 `CONFIG_UPROBE_EVENTS=y`로 빌드해야 합니다. kprobe 이벤트 추적기와 마찬가지로 `current_tracer`를 통해 활성화할 필요는 없습니다.

프로브 지점은 `/sys/kernel/tracing/uprobe_events`에 추가하고, 만들어진 이벤트는 `/sys/kernel/tracing/events/uprobes/<EVENT>/enable`에서 활성화합니다. 등록과 실행 허용이 서로 분리되어 있으므로 이벤트를 정의한 직후에는 아직 추적되지 않습니다.

kprobe 이벤트와 중요한 차이는 사용자가 객체 안에서 프로브 지점의 파일 오프셋을 직접 계산해야 한다는 점입니다. 런타임 가상 주소를 그대로 쓰는 것이 아니라, 실행 파일이나 라이브러리 내부의 `PATH:OFFSET`을 지정합니다.

`/sys/kernel/tracing/uprobe_events` 대신 `/sys/kernel/tracing/dynamic_events`를 사용할 수도 있습니다. 후자는 여러 종류의 동적 이벤트를 하나의 인터페이스에서 다룰 수 있게 합니다.

uprobe 이벤트 수명 주기
Build kernelCONFIG_UPROBE_EVENTS=y
Calculate object offsetPATH:OFFSET
Register/sys/kernel/tracing/uprobe_events
Enableevents/uprobes/<EVENT>/enable
Read/sys/kernel/tracing/trace

프로브를 등록한 뒤 별도로 활성화하고 trace 버퍼에서 결과를 읽습니다.

uprobe 제어 파일
경로역할
uprobe_eventsuprobe와 uretprobe 정의를 추가하거나 제거
dynamic_events다른 동적 이벤트와 함께 통합 관리
events/uprobes/<EVENT>/enable생성된 이벤트의 기록 활성화

등록, 통합 등록, 개별 활성화에 쓰이는 tracefs 경로입니다.

=========================================
Uprobe-tracer: Uprobe-based Event Tracing
=========================================

:Author: Srikar Dronamraju


Overview
--------
Uprobe based trace events are similar to kprobe based trace events.
To enable this feature, build your kernel with CONFIG_UPROBE_EVENTS=y.

Similar to the kprobe-event tracer, this doesn't need to be activated via
current_tracer. Instead of that, add probe points via
/sys/kernel/tracing/uprobe_events, and enable it via
/sys/kernel/tracing/events/uprobes/<EVENT>/enable.

However unlike kprobe-event tracer, the uprobe event interface expects the
user to calculate the offset of the probepoint in the object.

You can also use /sys/kernel/tracing/dynamic_events instead of
uprobe_events. That interface will provide unified access to other
dynamic events too.

등록 구문과 FETCHARGS

25-60

`p`는 함수 진입 등 지정 오프셋에 uprobe를 만들고, `r` 또는 `OFFSET%return`은 반환 시점을 잡는 uretprobe를 만듭니다. `-:[GRP/][EVENT]` 형식은 등록된 이벤트를 제거합니다.

  p[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS] : Set a uprobe
  r[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe)
  p[:[GRP/][EVENT]] PATH:OFFSET%return [FETCHARGS] : Set a return uprobe (uretprobe)
  -:[GRP/][EVENT]                           : Clear uprobe or uretprobe event

`GRP`를 생략하면 기본 그룹은 `uprobes`입니다. `EVENT`를 생략하면 `PATH+OFFSET`을 바탕으로 이름이 생성됩니다. `PATH`는 실행 파일 또는 라이브러리 경로이고 `OFFSET`은 그 객체 안에서 프로브를 삽입할 위치입니다.

uprobe 등록 구문
형식의미
p[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS]지정 위치에 uprobe 등록
r[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS]uretprobe 등록
p[:[GRP/][EVENT]] PATH:OFFSET%return [FETCHARGS]대체 반환 프로브 표기
-:[GRP/][EVENT]uprobe 또는 uretprobe 제거

일반 프로브, 반환 프로브, 제거 명령을 구분합니다.

각 프로브에는 최대 128개의 `FETCHARGS`를 둘 수 있습니다. `%REG`는 레지스터, `@ADDR`는 사용자 공간의 절대 주소, `@+OFFSET`은 `PATH`와 같은 파일 안의 오프셋에서 메모리를 가져옵니다.

`$stackN`은 0 이상인 N번째 스택 항목, `$stack`은 스택 주소, `$retval`은 반환값, `$comm`은 현재 태스크의 comm을 가져옵니다. `$retval`은 반환 프로브에서만 유효합니다.

`+|-[u]OFFS(FETCHARG)`는 기존 fetch 인수가 가리키는 주소에 오프셋을 더하거나 빼서 구조체 필드 등을 읽습니다. uprobe는 사용자 공간 메모리만 접근하므로 kprobe 구문에서의 `u` 접두사는 여기서 무시됩니다.

`\IMM`은 즉시값을 인수에 저장합니다. `NAME=FETCHARG`로 인수 이름을 붙이고 `FETCHARG:TYPE`으로 형식을 지정합니다. 지원 형식은 정수, 16진수, `string`, bitfield입니다.

FETCHARGS 선택자
선택자가져오는 값
%REG레지스터 REG
@ADDR / @+OFFSET사용자 주소 또는 같은 객체의 파일 오프셋
$stackN / $stackN번째 스택 항목 또는 스택 주소
$retval반환 프로브의 반환값
$comm현재 태스크 이름
+|-OFFS(FETCHARG)기준 주소에서 이동한 메모리
\IMM즉시값
NAME=FETCHARG / FETCHARG:TYPE이름 또는 출력 형식 지정

값을 가져오는 위치와 제약을 한눈에 정리합니다.

Synopsis of uprobe_tracer
-------------------------
::

  p[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS] : Set a uprobe
  r[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe)
  p[:[GRP/][EVENT]] PATH:OFFSET%return [FETCHARGS] : Set a return uprobe (uretprobe)
  -:[GRP/][EVENT]                           : Clear uprobe or uretprobe event

  GRP           : Group name. If omitted, "uprobes" is the default value.
  EVENT         : Event name. If omitted, the event name is generated based
                  on PATH+OFFSET.
  PATH          : Path to an executable or a library.
  OFFSET        : Offset where the probe is inserted.
  OFFSET%return : Offset where the return probe is inserted.

  FETCHARGS     : Arguments. Each probe can have up to 128 args.
   %REG         : Fetch register REG
   @ADDR	: Fetch memory at ADDR (ADDR should be in userspace)
   @+OFFSET	: Fetch memory at OFFSET (OFFSET from same file as PATH)
   $stackN	: Fetch Nth entry of stack (N >= 0)
   $stack	: Fetch stack address.
   $retval	: Fetch return value.(\*1)
   $comm	: Fetch current task comm.
   +|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*2)(\*3)
   \IMM		: Store an immediate value to the argument.
   NAME=FETCHARG     : Set NAME as the argument name of FETCHARG.
   FETCHARG:TYPE     : Set TYPE as the type of FETCHARG. Currently, basic types
		       (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
		       (x8/x16/x32/x64), "string" and bitfield are supported.

  (\*1) only for return probe.
  (\*2) this is useful for fetching a field of data structures.
  (\*3) Unlike kprobe event, "u" prefix will just be ignored, because uprobe
        events can access only user-space memory.

자료형과 이벤트 프로파일

61-84

fetch 인수의 자료형은 메모리 접근 폭과 표시 방식을 함께 결정합니다. `s` 접두사는 부호 있는 값, `u`는 부호 없는 값을 뜻하며 둘 다 10진수로 표시됩니다. `x` 접두사는 부호 없는 값을 16진수로 표시합니다.

명시적 형 변환이 없으면 아키텍처에 따라 `x32` 또는 `x64`가 기본입니다. 예를 들어 x86-32는 `x32`, x86-64는 `x64`를 사용합니다.

`string`은 사용자 공간의 null 종료 문자열을 읽는 특수 형식입니다. bitfield는 비트 폭, 비트 오프셋, 컨테이너 크기 세 매개변수를 받으며 구문은 `b<bit-width>@<bit-offset>/<container-size>`입니다. 컨테이너 크기는 보통 32입니다.

 b<bit-width>@<bit-offset>/<container-size>

`$comm`의 기본 자료형은 `string`이며 다른 자료형을 지정하면 유효하지 않습니다.

fetch 자료형
형식접근과 표시
s8/s16/s32/s64부호 있는 정수, 10진수
u8/u16/u32/u64부호 없는 정수, 10진수
x8/x16/x32/x64부호 없는 정수, 16진수
string사용자 공간의 null 종료 문자열
bitfield지정 컨테이너의 일부 비트 추출

접두사와 출력 표현, 특수 형식의 의미입니다.

`/sys/kernel/tracing/uprobe_profile`에서는 이벤트별 프로브 적중 횟수를 확인할 수 있습니다. 첫 열은 파일 이름, 둘째 열은 이벤트 이름, 셋째 열은 적중 횟수입니다.

uprobe_profile 열
내용
1filename
2event name
3probe hit count

프로파일 파일의 세 열을 왼쪽부터 읽습니다.

Types
-----
Several types are supported for fetch-args. Uprobe tracer will access memory
by given type. Prefix 's' and 'u' means those types are signed and unsigned
respectively. 'x' prefix implies it is unsigned. Traced arguments are shown
in decimal ('s' and 'u') or hexadecimal ('x'). Without type casting, 'x32'
or 'x64' is used depends on the architecture (e.g. x86-32 uses x32, and
x86-64 uses x64).
String type is a special type, which fetches a "null-terminated" string from
user space.
Bitfield is another special type, which takes 3 parameters, bit-width, bit-
offset, and container-size (usually 32). The syntax is::

 b<bit-width>@<bit-offset>/<container-size>

For $comm, the default type is "string"; any other type is invalid.


Event Profiling
---------------
You can check the total number of probe hits per event via
/sys/kernel/tracing/uprobe_profile. The first column is the filename,
the second is the event name, the third is the number of probe hits.

기본 등록과 제거 예제

85-107

`/bin/bash`의 객체 오프셋 `0x4245c0`에 일반 uprobe를 추가하려면 `p` 정의를 `uprobe_events`에 씁니다. 같은 지점의 반환을 추적하려면 `r` 정의를 씁니다.

    echo 'p /bin/bash:0x4245c0' > /sys/kernel/tracing/uprobe_events

 * Add a probe as a new uretprobe event::

    echo 'r /bin/bash:0x4245c0' > /sys/kernel/tracing/uprobe_events

 * Unset registered event::

    echo '-:p_bash_0x4245c0' >> /sys/kernel/tracing/uprobe_events

자동 생성된 이벤트 이름 `p_bash_0x4245c0` 앞에 `-:`를 붙여 쓰면 그 이벤트만 제거됩니다. 등록 목록은 파일을 읽어 확인하고, 빈 내용을 쓰면 모든 이벤트를 지웁니다.

 * Print out the events that are registered::

    cat /sys/kernel/tracing/uprobe_events

 * Clear all events::

    echo > /sys/kernel/tracing/uprobe_events
기본 관리 작업
작업명령 의미
echo 'p ...' >일반 uprobe 정의
echo 'r ...' >반환 uprobe 정의
echo '-:EVENT' >>선택 이벤트 제거
cat현재 등록 이벤트 출력
echo >모든 이벤트 제거

uprobe_events 파일에 대한 쓰기와 읽기 작업입니다.

셸 리디렉션의 `>`와 `>>`는 예제의 현재 상태를 기준으로 선택해야 합니다. 첫 정의는 파일에 쓰고, 기존 정의를 유지하며 추가하거나 제거 명령을 보낼 때는 append 형식을 사용합니다.

Usage examples
--------------
 * Add a probe as a new uprobe event, write a new definition to uprobe_events
   as below (sets a uprobe at an offset of 0x4245c0 in the executable /bin/bash)::

    echo 'p /bin/bash:0x4245c0' > /sys/kernel/tracing/uprobe_events

 * Add a probe as a new uretprobe event::

    echo 'r /bin/bash:0x4245c0' > /sys/kernel/tracing/uprobe_events

 * Unset registered event::

    echo '-:p_bash_0x4245c0' >> /sys/kernel/tracing/uprobe_events

 * Print out the events that are registered::

    cat /sys/kernel/tracing/uprobe_events

 * Clear all events::

    echo > /sys/kernel/tracing/uprobe_events

zfree 오프셋 계산과 이벤트 등록

108-135

다음 예제는 `/bin/zsh`의 `zfree` 함수에서 명령 포인터와 `%ax` 레지스터를 덤프합니다. 먼저 실행 중인 zsh의 메모리 맵에서 실행 가능한 매핑 시작 주소 `0x00400000`을 확인하고, `objdump` 심볼 주소 `0x446420`을 찾습니다.

    # cd /sys/kernel/tracing/
    # cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp
    00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh
    # objdump -T /bin/zsh | grep -w zfree
    0000000000446420 g    DF .text  0000000000000012  Base        zfree

객체 내부 오프셋은 `0x446420 - 0x00400000 = 0x46420`입니다. ASLR 등으로 런타임 배치 주소가 달라질 수 있으므로 uprobe 정의에는 계산한 객체 오프셋을 넣습니다.

zfree 객체 오프셋 계산
Runtime zfree address0x446420
Object load base0x00400000
Subtract0x446420 - 0x00400000
PATH:OFFSET/bin/zsh:0x46420

런타임 심볼 주소에서 객체 매핑 기준 주소를 뺍니다.

진입 이벤트 이름은 `zfree_entry`, 반환 이벤트 이름은 `zfree_exit`로 정하고 둘 다 `%ip %ax`를 fetch 인수로 등록합니다. 사용자가 프로브 지점의 객체 오프셋을 명시적으로 계산해야 한다는 것이 이 예제의 핵심입니다.

    # echo 'p:zfree_entry /bin/zsh:0x46420 %ip %ax' > uprobe_events

And the same for the uretprobe would be::

    # echo 'r:zfree_exit /bin/zsh:0x46420 %ip %ax' >> uprobe_events

`uprobe_events`를 읽으면 두 이벤트가 기본 `uprobes` 그룹에 들어갔고, fetch 인수는 `arg1=%ip`, `arg2=%ax`로 이름 붙은 것을 확인할 수 있습니다.

We can see the events that are registered by looking at the uprobe_events file.
::

    # cat uprobe_events
    p:uprobes/zfree_entry /bin/zsh:0x00046420 arg1=%ip arg2=%ax
    r:uprobes/zfree_exit /bin/zsh:0x00046420 arg1=%ip arg2=%ax
zfree 이벤트 쌍
이벤트종류수집값
zfree_entryp: uprobe%ip, %ax
zfree_exitr: uretprobe%ip, %ax

같은 객체 오프셋에서 진입과 반환을 나누어 추적합니다.

Following example shows how to dump the instruction pointer and %ax register
at the probed text address. Probe zfree function in /bin/zsh::

    # cd /sys/kernel/tracing/
    # cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp
    00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh
    # objdump -T /bin/zsh | grep -w zfree
    0000000000446420 g    DF .text  0000000000000012  Base        zfree

0x46420 is the offset of zfree in object /bin/zsh that is loaded at
0x00400000. Hence the command to uprobe would be::

    # echo 'p:zfree_entry /bin/zsh:0x46420 %ip %ax' > uprobe_events

And the same for the uretprobe would be::

    # echo 'r:zfree_exit /bin/zsh:0x46420 %ip %ax' >> uprobe_events

.. note:: User has to explicitly calculate the offset of the probe-point
	in the object.

We can see the events that are registered by looking at the uprobe_events file.
::

    # cat uprobe_events
    p:uprobes/zfree_entry /bin/zsh:0x00046420 arg1=%ip arg2=%ax
    r:uprobes/zfree_exit /bin/zsh:0x00046420 arg1=%ip arg2=%ax

이벤트 format 파일 읽기

136-154

`events/uprobes/zfree_entry/format`은 생성된 이벤트 레코드의 이름, ID, 공통 필드와 uprobe 전용 필드, 출력 형식을 보여 줍니다.

    # cat events/uprobes/zfree_entry/format
    name: zfree_entry
    ID: 922
    format:
         field:unsigned short common_type;         offset:0;  size:2; signed:0;
         field:unsigned char common_flags;         offset:2;  size:1; signed:0;
         field:unsigned char common_preempt_count; offset:3;  size:1; signed:0;
         field:int common_pid;                     offset:4;  size:4; signed:1;
         field:int common_padding;                 offset:8;  size:4; signed:1;

         field:unsigned long __probe_ip;           offset:12; size:4; signed:0;
         field:u32 arg1;                           offset:16; size:4; signed:0;
         field:u32 arg2;                           offset:20; size:4; signed:0;

    print fmt: "(%lx) arg1=%lx arg2=%lx", REC->__probe_ip, REC->arg1, REC->arg2

`common_type`, `common_flags`, `common_preempt_count`, `common_pid`, `common_padding`은 trace 이벤트 공통 헤더입니다. 각 줄의 `offset`, `size`, `signed` 값으로 레코드 안의 배치와 해석 방법을 알 수 있습니다.

`__probe_ip`은 프로브가 걸린 명령 위치이고 `arg1`, `arg2`는 등록할 때 지정한 `%ip`, `%ax`에서 온 값입니다. 이 예제 format에서는 세 값이 `unsigned long` 또는 `u32`로 표현됩니다.

`print fmt`는 trace 출력에서 레코드가 문자열로 렌더링되는 방식을 정의합니다. `REC->__probe_ip`, `REC->arg1`, `REC->arg2`가 각각 표시 자리와 연결됩니다.

zfree_entry 레코드
필드역할
common_*모든 trace 이벤트가 공유하는 메타데이터
__probe_ip프로브 명령 주소
arg1등록된 첫 fetch 인수 %ip
arg2등록된 둘째 fetch 인수 %ax
print fmttrace 텍스트 출력 형식

공통 헤더 뒤에 uprobe 위치와 fetch 인수가 놓입니다.

Format of events can be seen by viewing the file events/uprobes/zfree_entry/format.
::

    # cat events/uprobes/zfree_entry/format
    name: zfree_entry
    ID: 922
    format:
         field:unsigned short common_type;         offset:0;  size:2; signed:0;
         field:unsigned char common_flags;         offset:2;  size:1; signed:0;
         field:unsigned char common_preempt_count; offset:3;  size:1; signed:0;
         field:int common_pid;                     offset:4;  size:4; signed:1;
         field:int common_padding;                 offset:8;  size:4; signed:1;

         field:unsigned long __probe_ip;           offset:12; size:4; signed:0;
         field:u32 arg1;                           offset:16; size:4; signed:0;
         field:u32 arg2;                           offset:20; size:4; signed:0;

    print fmt: "(%lx) arg1=%lx arg2=%lx", REC->__probe_ip, REC->arg1, REC->arg2

이벤트 활성화와 trace 해석

155-186

이벤트는 정의 직후 기본적으로 비활성화되어 있습니다. uprobes 그룹의 이벤트를 기록하려면 `events/uprobes/enable`에 1을 씁니다.

    # echo 1 > events/uprobes/enable

예제는 `tracing_on`을 1로 설정해 추적을 시작하고 20초 동안 기다린 뒤 0으로 되돌려 멈춥니다. 이벤트 자체는 `events/uprobes/enable`에 0을 써서 비활성화할 수 있습니다.

Lets start tracing, sleep for some time and stop tracing.
::

    # echo 1 > tracing_on
    # sleep 20
    # echo 0 > tracing_on

Also, you can disable the event by::

    # echo 0 > events/uprobes/enable
uprobe 기록 절차
echo 1 > events/uprobes/enableEnable event group
echo 1 > tracing_onStart recording
Run workload / sleep 20Collect hits
echo 0 > tracing_onStop recording
cat traceInspect records
echo 0 > events/uprobes/enableDisable events

이벤트 활성화와 전역 기록 스위치를 순서대로 제어합니다.

기록 결과는 `/sys/kernel/tracing/trace`에서 읽습니다. 출력에는 태스크와 PID, CPU, 타임스탬프, 이벤트 이름, 프로브 주소와 fetch 인수가 포함됩니다.

And you can see the traced information via /sys/kernel/tracing/trace.
::

    # cat trace
    # tracer: nop
    #
    #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
    #              | |       |          |         |
                 zsh-24842 [006] 258544.995456: zfree_entry: (0x446420) arg1=446420 arg2=79
                 zsh-24842 [007] 258545.000270: zfree_exit:  (0x446540 <- 0x446420) arg1=446540 arg2=0
                 zsh-24842 [002] 258545.043929: zfree_entry: (0x446420) arg1=446420 arg2=79
                 zsh-24842 [004] 258547.046129: zfree_exit:  (0x446540 <- 0x446420) arg1=446540 arg2=0

예시에서 PID 24842인 zsh가 uprobe를 발생시켰습니다. `zfree_entry`의 IP는 `0x446420`이고 ax 레지스터 내용은 79입니다. `zfree_exit`은 IP `0x446540`에서 발생했으며 대응하는 함수 진입 위치는 `0x446420`입니다.

trace 출력 해석
레코드관찰값
zfree_entryPID 24842, IP 0x446420, AX 79
zfree_exit반환 IP 0x446540, 진입 IP 0x446420

진입과 반환 레코드에서 확인되는 핵심 값입니다.

Right after definition, each event is disabled by default. For tracing these
events, you need to enable it by::

    # echo 1 > events/uprobes/enable

Lets start tracing, sleep for some time and stop tracing.
::

    # echo 1 > tracing_on
    # sleep 20
    # echo 0 > tracing_on

Also, you can disable the event by::

    # echo 0 > events/uprobes/enable

And you can see the traced information via /sys/kernel/tracing/trace.
::

    # cat trace
    # tracer: nop
    #
    #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
    #              | |       |          |         |
                 zsh-24842 [006] 258544.995456: zfree_entry: (0x446420) arg1=446420 arg2=79
                 zsh-24842 [007] 258545.000270: zfree_exit:  (0x446540 <- 0x446420) arg1=446540 arg2=0
                 zsh-24842 [002] 258545.043929: zfree_entry: (0x446420) arg1=446420 arg2=79
                 zsh-24842 [004] 258547.046129: zfree_exit:  (0x446540 <- 0x446420) arg1=446540 arg2=0

Output shows us uprobe was triggered for a pid 24842 with ip being 0x446420
and contents of ax register being 79. And uretprobe was triggered with ip at
0x446540 with counterpart function entry at 0x446420.