요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=========================================
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.
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.
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.
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
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 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
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.
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`를 사용할 수도 있습니다. 후자는 여러 종류의 동적 이벤트를 하나의 인터페이스에서 다룰 수 있게 합니다.
프로브를 등록한 뒤 별도로 활성화하고 trace 버퍼에서 결과를 읽습니다.
등록, 통합 등록, 개별 활성화에 쓰이는 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`은 그 객체 안에서 프로브를 삽입할 위치입니다.
일반 프로브, 반환 프로브, 제거 명령을 구분합니다.
각 프로브에는 최대 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입니다.
값을 가져오는 위치와 제약을 한눈에 정리합니다.
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-84fetch 인수의 자료형은 메모리 접근 폭과 표시 방식을 함께 결정합니다. `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`이며 다른 자료형을 지정하면 유효하지 않습니다.
접두사와 출력 표현, 특수 형식의 의미입니다.
`/sys/kernel/tracing/uprobe_profile`에서는 이벤트별 프로브 적중 횟수를 확인할 수 있습니다. 첫 열은 파일 이름, 둘째 열은 이벤트 이름, 셋째 열은 적중 횟수입니다.
프로파일 파일의 세 열을 왼쪽부터 읽습니다.
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
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_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
같은 객체 오프셋에서 진입과 반환을 나누어 추적합니다.
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`가 각각 표시 자리와 연결됩니다.
공통 헤더 뒤에 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
이벤트 활성화와 전역 기록 스위치를 순서대로 제어합니다.
기록 결과는 `/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`입니다.
진입과 반환 레코드에서 확인되는 핵심 값입니다.
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.
요약·해설
uprobetracer.rst:1-186uprobe는 사용자 공간 객체의 파일 오프셋에 동적 trace 이벤트를 설치합니다. 객체 기준 오프셋을 정확히 계산하고, 프로브 등록과 이벤트 활성화를 구분하며, fetch 인수의 자료형과 반환 프로브 제약을 지키는 것이 핵심입니다.