[20260824]bpftrace的str和buf函数使用问题.txt
[20260824]bpftrace的str和buf函数使用问题.txt
--//使用bpftrace脚本使用str与buf函数遇到的问题,通过例子说明问题:
1.环境:
SYS@book> @ ver2
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 21.0.0.0.0
BANNER : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
$ bpftrace -V
bpftrace v0.24.2
2.测试bpftrace脚本:
$ cat dc_hash.bt
BEGIN
{
printf("Tracing Oracle kgghash... Target PID: %d\n", $1);
printf("Hit Ctrl-C to stop.\n\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("\nkrqhsh Begin\n");
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("krqhsh End\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
@kgg++;
@is_kgg[pid] = 1;
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x hash_text_ascii = ", strftime("%H:%M:%S", nsecs), @kgg, pid,str(arg0,arg1+1),arg1,arg2);
// print(buf(str(arg0,arg1+1),arg1));
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
printf("xxxx = %s %s %s\n",str(arg0,arg1),str(arg0,arg1+1),buf(arg0,arg1));
printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(arg0,arg1), arg1,arg2);
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
if (@is_kgg[pid] == 1) {
printf("[%s] kgghash #%02d pid=%d return hash_value=%016lx %ld %016lx %d\n", strftime("%H:%M:%S", nsecs), @kgg,pid, retval, retval, retval%32768,retval%32768);
delete(@is_kgg[pid]);
}
}
END
{
printf("\nTotal kgghash: %d\n", @kgg);
delete(@kgg);
}
--//执行:
SYS@book> @ spid
==============================
SID : 2
SERIAL# : 12100
PROCESS : 3218
SERVER : DEDICATED
SPID : 3219
PID : 8
P_SERIAL# : 9
KILL_COMMAND : alter system kill session '2,12100' immediate;
PL/SQL procedure successfully completed.
--//执行select sid from v$mystat where rownum=1;多次,在使用bpftrace脚本跟踪。
SYS@book> select sid from v$mystat where rownum=1;
SID
----------
2
--//执行输出如下:
# bpftrace ./dc_hash.bt 3219
Attached 6 probes
Tracing Oracle kgghash... Target PID: 3219
Hit Ctrl-C to stop.
xxxx = CDB$ROO CDB$ROOT CDB$ROOT
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[09:30:16] kgghash #01 pid=3219 hash_text=CDB$ROOT length=8 seed=0
[09:30:16] kgghash #01 pid=3219 return hash_value=000000001eee6512 518939922 0000000000006512 25874
--//看下划线,arg1=8,str(arg0,arg1)的输出仅仅CDB$ROO,长度7。而修改为str(arg0,arg1+1),才是完整的输出。
--//可以看出str 参数2实际上输出长度 是 参数2-1.
--//而buf函数的输出参数2就是输出的长度,不过长度不足可以发现补充\x00,可以自行测试。
krqhsh Begin
xxxx = \xc3\xc0\xff\xff
[09:30:16] kgghash #02 pid=3219 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[09:30:16] kgghash #02 pid=3219 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
xxxx = CDB$ROO CDB$ROOT CDB$ROOT
[09:30:16] kgghash #03 pid=3219 hash_text=CDB$ROOT length=8 seed=f28adaf8
[09:30:16] kgghash #03 pid=3219 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
krqhsh End
krqhsh Begin
xxxx = \xc3\xc0\xff\xff
[09:30:16] kgghash #04 pid=3219 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[09:30:16] kgghash #04 pid=3219 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
xxxx = CDB$ROO CDB$ROOT CDB$ROOT
[09:30:16] kgghash #05 pid=3219 hash_text=CDB$ROOT length=8 seed=f28adaf8
[09:30:16] kgghash #05 pid=3219 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
krqhsh End
krqhsh Begin
xxxx = \xfa\xc3\xff\xff
[09:30:16] kgghash #06 pid=3219 hash_text=\xfa\xc3\xff\xff length=4 seed=0
[09:30:16] kgghash #06 pid=3219 return hash_value=00000000368bf4a4 915141796 00000000000074a4 29860
xxxx = CDB$ROO CDB$ROOT CDB$ROOT
[09:30:16] kgghash #07 pid=3219 hash_text=CDB$ROOT length=8 seed=368bf4a4
[09:30:16] kgghash #07 pid=3219 return hash_value=0000000040d79a79 1087871609 0000000000001a79 6777
krqhsh End
krqhsh Begin
xxxx = \xfa\xc3\xff\xff
[09:30:16] kgghash #08 pid=3219 hash_text=\xfa\xc3\xff\xff length=4 seed=0
[09:30:16] kgghash #08 pid=3219 return hash_value=00000000368bf4a4 915141796 00000000000074a4 29860
xxxx = CDB$ROO CDB$ROOT CDB$ROOT
[09:30:16] kgghash #09 pid=3219 hash_text=CDB$ROOT length=8 seed=368bf4a4
[09:30:16] kgghash #09 pid=3219 return hash_value=0000000040d79a79 1087871609 0000000000001a79 6777
krqhsh End
xxxx =
\x0b\x00\x01\x00\x00\x00\x00\x00
[09:30:16] kgghash #10 pid=3219 hash_text=\x0b\x00\x00\x00\x00\x00\x00\x00 length=8 seed=0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[09:30:16] kgghash #10 pid=3219 return hash_value=00000000ceb5d99e 3468024222 000000000000599e 22942
^C
Total kgghash: 10
--//看xxxx出现折行,不过最后ascii码的输出是\x0b\x00\x01\x00\x00\x00\x00\x00,而下划线行输出
--//\x0b\x00\x00\x00\x00\x00\x00\x00. 两者存在完全不同。
--//执行的是buf(str(arg0,arg1+1),arg1),str(arg0,arg1+1),arg0地址指向的字符串包含\x00,导致被截断变成\x0b,
--//再执行buf时补齐变成了\x0b\x00\x00\x00\x00\x00\x00\x00,写代码有点画蛇添足了。直接写buf(arg0,arg1)就可以了。
--//修改后的脚本如下:
$ cat dc_hash.bt
BEGIN
{
printf("Tracing Oracle kgghash... Target PID: %d\n", $1);
printf("Hit Ctrl-C to stop.\n\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("\nkrqhsh Begin\n");
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("krqhsh End\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
@kgg++;
@is_kgg[pid] = 1;
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x hash_text_ascii = ", strftime("%H:%M:%S", nsecs), @kgg, pid,str(arg0,arg1+1),arg1,arg2);
// print(buf(str(arg0,arg1+1),arg1));
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
// printf("xxxx = %s %s %s\n",str(arg0,arg1),str(arg0,arg1+1),buf(arg0,arg1));
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(arg0,arg1), arg1,arg2);
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
if (@is_kgg[pid] == 1) {
printf("[%s] kgghash #%02d pid=%d return hash_value=%016lx %ld %016lx %d\n", strftime("%H:%M:%S", nsecs), @kgg,pid, retval, retval, retval%32768,retval%32768);
delete(@is_kgg[pid]);
}
}
END
{
printf("\nTotal kgghash: %d\n", @kgg);
delete(@kgg);
}
--//使用bpftrace脚本使用str与buf函数遇到的问题,通过例子说明问题:
1.环境:
SYS@book> @ ver2
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 21.0.0.0.0
BANNER : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
$ bpftrace -V
bpftrace v0.24.2
2.测试bpftrace脚本:
$ cat dc_hash.bt
BEGIN
{
printf("Tracing Oracle kgghash... Target PID: %d\n", $1);
printf("Hit Ctrl-C to stop.\n\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("\nkrqhsh Begin\n");
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("krqhsh End\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
@kgg++;
@is_kgg[pid] = 1;
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x hash_text_ascii = ", strftime("%H:%M:%S", nsecs), @kgg, pid,str(arg0,arg1+1),arg1,arg2);
// print(buf(str(arg0,arg1+1),arg1));
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
printf("xxxx = %s %s %s\n",str(arg0,arg1),str(arg0,arg1+1),buf(arg0,arg1));
printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(arg0,arg1), arg1,arg2);
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
if (@is_kgg[pid] == 1) {
printf("[%s] kgghash #%02d pid=%d return hash_value=%016lx %ld %016lx %d\n", strftime("%H:%M:%S", nsecs), @kgg,pid, retval, retval, retval%32768,retval%32768);
delete(@is_kgg[pid]);
}
}
END
{
printf("\nTotal kgghash: %d\n", @kgg);
delete(@kgg);
}
--//执行:
SYS@book> @ spid
==============================
SID : 2
SERIAL# : 12100
PROCESS : 3218
SERVER : DEDICATED
SPID : 3219
PID : 8
P_SERIAL# : 9
KILL_COMMAND : alter system kill session '2,12100' immediate;
PL/SQL procedure successfully completed.
--//执行select sid from v$mystat where rownum=1;多次,在使用bpftrace脚本跟踪。
SYS@book> select sid from v$mystat where rownum=1;
SID
----------
2
--//执行输出如下:
# bpftrace ./dc_hash.bt 3219
Attached 6 probes
Tracing Oracle kgghash... Target PID: 3219
Hit Ctrl-C to stop.
xxxx = CDB$ROO CDB$ROOT CDB$ROOT
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[09:30:16] kgghash #01 pid=3219 hash_text=CDB$ROOT length=8 seed=0
[09:30:16] kgghash #01 pid=3219 return hash_value=000000001eee6512 518939922 0000000000006512 25874
--//看下划线,arg1=8,str(arg0,arg1)的输出仅仅CDB$ROO,长度7。而修改为str(arg0,arg1+1),才是完整的输出。
--//可以看出str 参数2实际上输出长度 是 参数2-1.
--//而buf函数的输出参数2就是输出的长度,不过长度不足可以发现补充\x00,可以自行测试。
krqhsh Begin
xxxx = \xc3\xc0\xff\xff
[09:30:16] kgghash #02 pid=3219 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[09:30:16] kgghash #02 pid=3219 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
xxxx = CDB$ROO CDB$ROOT CDB$ROOT
[09:30:16] kgghash #03 pid=3219 hash_text=CDB$ROOT length=8 seed=f28adaf8
[09:30:16] kgghash #03 pid=3219 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
krqhsh End
krqhsh Begin
xxxx = \xc3\xc0\xff\xff
[09:30:16] kgghash #04 pid=3219 hash_text=\xc3\xc0\xff\xff length=4 seed=0
[09:30:16] kgghash #04 pid=3219 return hash_value=00000000f28adaf8 4069186296 0000000000005af8 23288
xxxx = CDB$ROO CDB$ROOT CDB$ROOT
[09:30:16] kgghash #05 pid=3219 hash_text=CDB$ROOT length=8 seed=f28adaf8
[09:30:16] kgghash #05 pid=3219 return hash_value=0000000046ad9a7a 1185782394 0000000000001a7a 6778
krqhsh End
krqhsh Begin
xxxx = \xfa\xc3\xff\xff
[09:30:16] kgghash #06 pid=3219 hash_text=\xfa\xc3\xff\xff length=4 seed=0
[09:30:16] kgghash #06 pid=3219 return hash_value=00000000368bf4a4 915141796 00000000000074a4 29860
xxxx = CDB$ROO CDB$ROOT CDB$ROOT
[09:30:16] kgghash #07 pid=3219 hash_text=CDB$ROOT length=8 seed=368bf4a4
[09:30:16] kgghash #07 pid=3219 return hash_value=0000000040d79a79 1087871609 0000000000001a79 6777
krqhsh End
krqhsh Begin
xxxx = \xfa\xc3\xff\xff
[09:30:16] kgghash #08 pid=3219 hash_text=\xfa\xc3\xff\xff length=4 seed=0
[09:30:16] kgghash #08 pid=3219 return hash_value=00000000368bf4a4 915141796 00000000000074a4 29860
xxxx = CDB$ROO CDB$ROOT CDB$ROOT
[09:30:16] kgghash #09 pid=3219 hash_text=CDB$ROOT length=8 seed=368bf4a4
[09:30:16] kgghash #09 pid=3219 return hash_value=0000000040d79a79 1087871609 0000000000001a79 6777
krqhsh End
xxxx =
\x0b\x00\x01\x00\x00\x00\x00\x00
[09:30:16] kgghash #10 pid=3219 hash_text=\x0b\x00\x00\x00\x00\x00\x00\x00 length=8 seed=0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[09:30:16] kgghash #10 pid=3219 return hash_value=00000000ceb5d99e 3468024222 000000000000599e 22942
^C
Total kgghash: 10
--//看xxxx出现折行,不过最后ascii码的输出是\x0b\x00\x01\x00\x00\x00\x00\x00,而下划线行输出
--//\x0b\x00\x00\x00\x00\x00\x00\x00. 两者存在完全不同。
--//执行的是buf(str(arg0,arg1+1),arg1),str(arg0,arg1+1),arg0地址指向的字符串包含\x00,导致被截断变成\x0b,
--//再执行buf时补齐变成了\x0b\x00\x00\x00\x00\x00\x00\x00,写代码有点画蛇添足了。直接写buf(arg0,arg1)就可以了。
--//修改后的脚本如下:
$ cat dc_hash.bt
BEGIN
{
printf("Tracing Oracle kgghash... Target PID: %d\n", $1);
printf("Hit Ctrl-C to stop.\n\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("\nkrqhsh Begin\n");
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kqrhsh
/ $1 == 0 || pid == $1 /
{
printf("krqhsh End\n");
}
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
@kgg++;
@is_kgg[pid] = 1;
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x hash_text_ascii = ", strftime("%H:%M:%S", nsecs), @kgg, pid,str(arg0,arg1+1),arg1,arg2);
// print(buf(str(arg0,arg1+1),arg1));
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
// printf("xxxx = %s %s %s\n",str(arg0,arg1),str(arg0,arg1+1),buf(arg0,arg1));
// printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(str(arg0,arg1+1),arg1), arg1,arg2);
printf("[%s] kgghash #%02d pid=%d hash_text=%s length=%d seed=%x \n", strftime("%H:%M:%S", nsecs), @kgg, pid,buf(arg0,arg1), arg1,arg2);
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:kgghash
/ $1 == 0 || pid == $1 /
{
if (@is_kgg[pid] == 1) {
printf("[%s] kgghash #%02d pid=%d return hash_value=%016lx %ld %016lx %d\n", strftime("%H:%M:%S", nsecs), @kgg,pid, retval, retval, retval%32768,retval%32768);
delete(@is_kgg[pid]);
}
}
END
{
printf("\nTotal kgghash: %d\n", @kgg);
delete(@kgg);
}
浙公网安备 33010602011771号