认为最主要是因为不清楚内核中都有哪些函数和跟踪点可以拿来跟踪。
第一个,kfree_skb ,它经常在网络异常丢包时调用;第二个,consume_skb ,它在正常网络连接完成时调用
sudo ./bpftrace -e 'kprobe:kfree_skb /comm=="curl"/ {printf("kstack: %s\n", kstack);}'
curl time.geekbang.org
kprobe:kfree_skb 指定跟踪的内核函数为 kfree_skb;
紧随其后的 /comm=="curl"/ ,表示只跟踪 curl 进程,这是为了过滤掉其他不相关的进程操作
kprobe:kfree_skb /comm=="curl"/
{
// 1. 第一个参数是 struct sk_buff
$skb = (struct sk_buff *)arg0;
// 2. 从网络头中获取源IP和目的IP
$iph = (struct iphdr *)($skb->head + $skb->network_header);
$sip = ntop(AF_INET, $iph->saddr);
$dip = ntop(AF_INET, $iph->daddr);
// 3. 只处理TCP协议
if ($iph->protocol == IPPROTO_TCP)
{
// 4. 打印源IP、目的IP和内核调用栈
printf("SKB dropped: %s->%s, kstack: %s\n", $sip, $dip, kstack);
}
}