![](/img/trans.png)
[英]kprobe of tcp_retransmit_skb. instead of tcp_retransmit_skb @tcp_states, I want to kprobe __napi_schedule
[英]How can I use the enum tcp mib definitions in a kprobe program?
在這里,我嘗試編寫一個程序(kprobe),以在 BPF Performance Tools bpftrace 一書中包含像 @tcp_states 這樣的 enum tcp mib。 枚舉 tcp mib 位於“/include/uapi/linux/snmp.h”中:
#!/usr/local/bin/bpftrace
#include <net/net_namespace.h>
#include <net/netns/mib.h>
#include <net/snmp.h>
#include <uapi/linux/snmp.h>
#define TCP_MIB_MAX __TCP_MIB_MAX
kprobe:sk_alloc
{
$net = (struct net *)arg0;
$mi = (struct netns_mib *)$net->mib;
$ib = (struct tcp_mib *)$mi;
@mib[1] = "TCP_MIB_NUM";
@mib[2] = "TCP_MIB_RTOALGORITHM";
@mib[3] = "TCP_MIB_RTOMIN";
@mib[4] = "TCP_MIB_RTOMAX;
@mib[5] = "TCP_MIB_MAXCONN";
@mib[6] = "TCP_MIB_ACTIVEOPENS";
@mib[7] = "TCP_MIB_PASSIVEOPENS";
@mib[8] = "TCP_MIB_ATTEMPTFAILS";
@mib[9] = "TCP_MIB_ESTABRESETS";
@mib[10] = "TCP_MIB_CURRESTAB";
@mib[11] = "TCP_MIB_INSEGS";
@mib[12] = "TCP_MIB_OUTSEGS";
@mib[13] = "TCP_MIB_RETRANSSEGS";
@mib[14] = "TCP_MIB_INERRS";
@mib[15] = "TCP_MIB_OUTRSTS";
@mib[16] = "TCP_MIB_CSUMERRORS";
printf("-------------------------------\n");
time();
printf("sk_alloc: %s pid: %d\n", comm, pid);
printf("\n");
printf("$ib: %u\n", $ib->miss[6]);
$mib_s = $ib->mibs[TCP_MIB_MAX];
$mib_str = @mib[$mib_s];
printf("TCP mib is: %s\n", $mib_str);
clear(@mib);
}
當我嘗試運行它時,輸出是:
the index 94779518808448 is out of bounds for array of size 16
然后我嘗試代替 TCP_MIB_MAX,放置特定的數組位置,例如 5,(我修改了上面的代碼):
$mib_s = $ib->mibs[5];
當我嘗試運行它時,輸出是:
...
-----------------------------
21:40:15
sk_alloc: systemd-logind pid: 920
$ib: 1516359680
TCP mib is:
-----------------------------
21:40:15
sk_alloc: systemd-logind pid: 920
$ib: 1516359680
TCP mib is:
...
為什么不顯示 TCP mib? 並且在輸出中什么都不顯示? 如何正確使用數組來顯示@mib?
TCP_MIB_MAX
和__TCP_MIB_MAX
等於16,等於內核中struct tcp_mib
的大小:
enum
{
TCP_MIB_NUM = 0,
TCP_MIB_RTOALGORITHM, /* RtoAlgorithm */
TCP_MIB_RTOMIN, /* RtoMin */
TCP_MIB_RTOMAX, /* RtoMax */
TCP_MIB_MAXCONN, /* MaxConn */
TCP_MIB_ACTIVEOPENS, /* ActiveOpens */
TCP_MIB_PASSIVEOPENS, /* PassiveOpens */
TCP_MIB_ATTEMPTFAILS, /* AttemptFails */
TCP_MIB_ESTABRESETS, /* EstabResets */
TCP_MIB_CURRESTAB, /* CurrEstab */
TCP_MIB_INSEGS, /* InSegs */
TCP_MIB_OUTSEGS, /* OutSegs */
TCP_MIB_RETRANSSEGS, /* RetransSegs */
TCP_MIB_INERRS, /* InErrs */
TCP_MIB_OUTRSTS, /* OutRsts */
TCP_MIB_CSUMERRORS, /* InCsumErrors */ // == 15
__TCP_MIB_MAX // == 16
};
和
#define TCP_MIB_MAX __TCP_MIB_MAX
struct tcp_mib {
unsigned long mibs[TCP_MIB_MAX];
};
(包含/uapi/linux/snmp.h 和包含/net/snmp.h)
但是因為數組是從 0 開始索引的,所以在索引$ib->mibs
時你只能達到TCP_MIB_MAX - 1
。 這就是為什么您會收到有關越界索引的投訴。
然后當您選擇較小的索引時,您可以按預期訪問數組項。 但我不確定你想做什么:
$mib_s = $ib->mibs[5];
$mib_str = @mib[$mib_s];
對我來說,您似乎正在從 MIB ( $ib->mibs[TCP_MIB_ACTIVEOPENS]
) 讀取值,它可能提供任何值,可能很大,也可能為 null(我懷疑這里就是這種情況)。 然后您將該值用作... @mib
的索引? 因此,如果計數器為 10k,您嘗試獲取 16 大小數組的第 10,000 個單元格? 我想在您的情況下,該值為 0,因此您正在執行$mib_str = @mib[0]
,這可能是一個空字符串,因為您從未為@mib[0]
設置值。
為了解決所有這些問題,我將首先為@mib
數組使用正確的索引(從 0 到 15),以避免任何混淆。 然后您可能需要重新考慮您要准確打印的內容,但我不確定上面的兩行是否是您想要的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.