[20260703]跟踪library cache lock library cache pin的bpftrace脚本转换为bcc脚本
--//首先说明bcc的脚本不是我写的,是使用kimi生成,仅仅提供bpftrace脚本。
$ cat lkpn21c.bt
#!/usr/bin/env bpftrace
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgllkal
/ $1 == 0 || pid == $1 /
{
@lk++;
printf("kgllkal count %02d -- handle address: %016lx, mode: %d ", @lk, arg2, arg3);
printf("spid %d ",pid);
printf("kglnaobj address: %s\n", str(arg2 + 0x1c8, 256));
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kglpnal
/ $1 == 0 || pid == $1 /
{
@pn++;
printf("kglpnal count %02d -- handle address: %016lx, mode: %d ", @pn, arg2, arg3);
printf("spid %d ",pid);
printf("kglnaobj address: %s\n", str(arg2 + 0x1c8, 256));
}
--//希望生成bcc执行脚本。生成脚本保存为lkpn21c 设置权限755后执行。
# chmod 755 ./lkpn21c
--//执行报如下错误:
# ./lkpn21c 3156
Traceback (most recent call last):
File "/home/oracle/study/202606/./lkpn21c", line 149, in <module>
b.attach_uprobe(name=oracle_path, sym="kgllkal", fn_name="trace_kgllkal_entry")
File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 1462, in attach_uprobe
fn = self.load_func(fn_name, BPF.KPROBE)
File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 535, in load_func
raise Exception("Unknown program %s" % func_name)
Exception: Unknown program b'trace_kgllkal_entry'
--//将错误提示给kimi分析,给出建议删除前面static。
static int trace_kglpnal_entry(struct pt_regs *ctx)
--//修改为:
int trace_kglpnal_entry(struct pt_regs *ctx)
--//再次执行正常,但是输出乱码。修改
data.handle = PT_REGS_PARM2(ctx);
data.mode = PT_REGS_PARM3(ctx);
--//修改如下:
data.handle = PT_REGS_PARM3(ctx);
data.mode = PT_REGS_PARM4(ctx);
--//感觉AI应该不会犯这类低级的错误。再次执行正常,另外生成的时间不对,也许是时区导致的问题,取消输出。
--//感觉AI确实厉害,整个过程几乎没写一行代码,虽然存在错误,很快做了更正。
# /home/oracle/study/202606/lkpn21c 3392
Tracing Oracle kgllkal/kglpnal... Press Ctrl-C to stop.
Filter: PID = 3392
kgllkal count 04 -- handle address: 000000006d5f4b98, mode: 1 kglnaobj address: select * from dept where deptno=25
kglpnal count 02 -- handle address: 000000006d5f4b98, mode: 2 kglnaobj address: select * from dept where deptno=25
kgllkal count 05 -- handle address: 0000000072922f58, mode: 2 kglnaobj address: bookSYSCDB$ROOT
kgllkal count 06 -- handle address: 000000006ddc26b0, mode: 2 kglnaobj address: 1847639831SYSCDB$ROOT
kgllkal count 07 -- handle address: 000000006d7e87f8, mode: 2 kglnaobj address: f9f8a42e053dc04b9d42e6bb0296489b$BUILD$BOOK01P
kgllkal count 08 -- handle address: 000000006d7e85c8, mode: 1 kglnaobj address:
kglpnal count 03 -- handle address: 000000006d7e85c8, mode: 3 kglnaobj address:
kgllkal count 09 -- handle address: 0000000072922f58, mode: 2 kglnaobj address: bookSYSCDB$ROOT
kgllkal count 10 -- handle address: 000000006ddc26b0, mode: 2 kglnaobj address: 1847639831SYSCDB$ROOT
kgllkal count 11 -- handle address: 000000006d941e78, mode: 1 kglnaobj address: f9f8a42e053dc04b9d42e6bb0296489bChild:0BOOK01P
kglpnal count 04 -- handle address: 000000006d941e78, mode: 3 kglnaobj address: f9f8a42e053dc04b9d42e6bb0296489bChild:0BOOK01P
kgllkal count 12 -- handle address: 0000000063e376d0, mode: 1 kglnaobj address: SCOTTBOOK01P
kgllkal count 13 -- handle address: 0000000072922f58, mode: 2 kglnaobj address: bookSYSCDB$ROOT
kgllkal count 14 -- handle address: 000000006ddc26b0, mode: 2 kglnaobj address: 1847639831SYSCDB$ROOT
kgllkal count 15 -- handle address: 0000000063d60ed0, mode: 2 kglnaobj address: DEPTSCOTTBOOK01P@??c
kglpnal count 05 -- handle address: 0000000063d60ed0, mode: 2 kglnaobj address: DEPTSCOTTBOOK01P@??c
kgllkal count 16 -- handle address: 000000006fa2b558, mode: 2 kglnaobj address: 356430430180546253BOOK01P
kglpnal count 06 -- handle address: 000000006fa2b558, mode: 2 kglnaobj address: 356430430180546253BOOK01P
kgllkal count 17 -- handle address: 000000006fa76598, mode: 2 kglnaobj address: 7574277674127661070BOOK01P
kglpnal count 07 -- handle address: 000000006fa76598, mode: 2 kglnaobj address: 7574277674127661070BOOK01P
kgllkal count 18 -- handle address: 000000006fc062c8, mode: 2 kglnaobj address: 4204170303842060717BOOK01P
kglpnal count 08 -- handle address: 000000006fc062c8, mode: 2 kglnaobj address: 4204170303842060717BOOK01P
kgllkal count 19 -- handle address: 000000006fabe748, mode: 2 kglnaobj address: 5467474030038125289BOOK01P
kglpnal count 09 -- handle address: 000000006fabe748, mode: 2 kglnaobj address: 5467474030038125289BOOK01P
kgllkal count 20 -- handle address: 000000006fa76598, mode: 2 kglnaobj address: 7574277674127661070BOOK01P
kglpnal count 10 -- handle address: 000000006fa76598, mode: 2 kglnaobj address: 7574277674127661070BOOK01P
kgllkal count 21 -- handle address: 000000006d5f4b98, mode: 1 kglnaobj address: select * from dept where deptno=25
kgllkal count 22 -- handle address: 000000006d7e85c8, mode: 1 kglnaobj address:
kgllkal count 23 -- handle address: 0000000063d60ed0, mode: 2 kglnaobj address: DEPTSCOTTBOOK01P@??c
kglpnal count 11 -- handle address: 0000000063d60ed0, mode: 2 kglnaobj address: DEPTSCOTTBOOK01P@??c
kgllkal count 24 -- handle address: 000000006d5f4b98, mode: 1 kglnaobj address: select * from dept where deptno=25
kgllkal count 25 -- handle address: 000000006d7e85c8, mode: 1 kglnaobj address:
--//源代码如下:
$ cat lkpn21c
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
BCC script to trace Oracle kgllkal and kglpnal
Equivalent to the bpftrace script:
uprobe:/u01/app/oracle/.../bin/oracle:kgllkal
/ $1 == 0 || pid == $1 /
{
@lk++;
printf("kgllkal count %02d -- handle address: %016lx, mode: %d ", @lk, arg2, arg3);
printf("kglnaobj address: %s\n", str(arg2 + 0x1c8, 256));
}
Usage: sudo python3 trace_oracle_kgl.py [PID]
"""
from bcc import BPF
import sys
import ctypes as ct
# Parse PID from command line
target_pid = int(sys.argv[1]) if len(sys.argv) > 1 else 0
# BPF C program
bpf_text = r"""
#include <uapi/linux/ptrace.h>
struct data_t {
u64 ts;
u32 pid;
u32 tid;
u64 handle;
u64 mode;
u64 count;
char type[8]; // "kgllkal" or "kglpnal"
char obj[256]; // object name from kglnaobj
};
BPF_PERF_OUTPUT(events);
// Global counters (single-element arrays in map)
BPF_ARRAY(lk_counter, u64, 1);
BPF_ARRAY(pn_counter, u64, 1);
// NOTE: do NOT use 'static' for functions attached by attach_uprobe,
// otherwise BCC cannot find the program and raises:
// Exception: Unknown program b'trace_kgllkal_entry'
int trace_kgllkal_entry(struct pt_regs *ctx)
{
u32 pid = bpf_get_current_pid_tgid() >> 32;
// Filter by PID if specified
u32 filter_pid = FILTER_PID;
if (filter_pid != 0 && pid != filter_pid) {
return 0;
}
struct data_t data = {};
data.ts = bpf_ktime_get_ns();
data.pid = pid;
data.tid = bpf_get_current_pid_tgid() & 0xFFFFFFFF;
data.handle = PT_REGS_PARM3(ctx);
data.mode = PT_REGS_PARM4(ctx);
// Increment global counter
u32 idx = 0;
u64 *cnt = lk_counter.lookup(&idx);
if (cnt) {
data.count = *cnt + 1;
lk_counter.update(&idx, &data.count);
} else {
data.count = 1;
u64 init = 1;
lk_counter.update(&idx, &init);
}
// Set type
__builtin_memcpy(data.type, "kgllkal", 8);
// Read object name from handle + 0x1c8 offset (user memory)
u64 obj_addr = data.handle + 0x1c8;
bpf_probe_read_user_str(&data.obj, sizeof(data.obj), (void *)obj_addr);
events.perf_submit(ctx, &data, sizeof(data));
return 0;
}
int trace_kglpnal_entry(struct pt_regs *ctx)
{
u32 pid = bpf_get_current_pid_tgid() >> 32;
// Filter by PID if specified
u32 filter_pid = FILTER_PID;
if (filter_pid != 0 && pid != filter_pid) {
return 0;
}
struct data_t data = {};
data.ts = bpf_ktime_get_ns();
data.pid = pid;
data.tid = bpf_get_current_pid_tgid() & 0xFFFFFFFF;
data.handle = PT_REGS_PARM2(ctx);
data.mode = PT_REGS_PARM3(ctx);
// Increment global counter
u32 idx = 0;
u64 *cnt = pn_counter.lookup(&idx);
if (cnt) {
data.count = *cnt + 1;
pn_counter.update(&idx, &data.count);
} else {
data.count = 1;
u64 init = 1;
pn_counter.update(&idx, &init);
}
// Set type
__builtin_memcpy(data.type, "kglpnal", 8);
// Read object name from handle + 0x1c8 offset (user memory)
u64 obj_addr = data.handle + 0x1c8;
bpf_probe_read_user_str(&data.obj, sizeof(data.obj), (void *)obj_addr);
events.perf_submit(ctx, &data, sizeof(data));
return 0;
}
"""
# Replace FILTER_PID with actual value
bpf_text = bpf_text.replace('FILTER_PID', str(target_pid))
# Load BPF program
b = BPF(text=bpf_text)
# Attach uprobes
oracle_path = "/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle"
b.attach_uprobe(name=oracle_path, sym="kgllkal", fn_name="trace_kgllkal_entry")
b.attach_uprobe(name=oracle_path, sym="kglpnal", fn_name="trace_kglpnal_entry")
# Define output structure matching struct data_t
class Data(ct.Structure):
_fields_ = [
("ts", ct.c_ulonglong),
("pid", ct.c_uint),
("tid", ct.c_uint),
("handle", ct.c_ulonglong),
("mode", ct.c_ulonglong),
("count", ct.c_ulonglong),
("type", ct.c_char * 8),
("obj", ct.c_char * 256),
]
# Print header
print("Tracing Oracle kgllkal/kglpnal... Press Ctrl-C to stop.")
if target_pid:
print("Filter: PID = {}".format(target_pid))
print()
# Process events
def print_event(cpu, data, size):
event = ct.cast(data, ct.POINTER(Data)).contents
# Convert nanoseconds to HH:MM:SS
secs = event.ts // 1000000000
hh = int(secs // 3600 % 24)
mm = int(secs // 60 % 60)
ss = int(secs % 60)
ts_str = "{:02d}:{:02d}:{:02d}".format(hh, mm, ss)
obj_str = event.obj.decode('utf-8', 'replace').strip('\x00')
type_str = event.type.decode('utf-8', 'replace').strip('\x00')
print("{} count {:02d} -- handle address: {:016x}, mode: {} kglnaobj address: {}".format(
type_str,
event.count,
event.handle,
event.mode,
obj_str
))
# Open perf buffer
b["events"].open_perf_buffer(print_event)
# Poll
while True:
try:
b.perf_buffer_poll()
except KeyboardInterrupt:
print("\n\nDone.")
break
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3175590/ ,如需转载,请注明出处,否则将追究法律责任。