zl程序教程

您现在的位置是:首页 >  其他

当前栏目

buffer又泄漏了,头大...

2023-02-19 12:21:06 时间

昨晚程序又出现buffer泄漏了,导致业务中断了,采集了一下基本的信息及手动生成vpp的core文件,就重启了程序。

通过show interface可以看到接口存在rx-no-buffer的错误统计。

公众号文章中输出过关于vpp 报文缓冲区buffer的介绍,特意把以前输出的文章放到了下面。

vlib ----buffer pool 内存初始化(1)

vlib ----buffer pool 内存初始化(2)

vpp buffer 泄露问题定位思路

vpp Buffer Metadata

DPDK-vpp 一次mbuf地址被踩的定位思路

vpp buffer 泄露问题定位思路文中,举例说明了dbug模式下通过开启VLIB_BUFFER_TRACE_TRAJECTORY宏来跟踪报文运行node节点方法,当时在vpp代码中并未找到具体的使用方法,就在昨晚vpp-dev邮件中找到了答案。

邮件链接:https://lists.fd.io/g/vpp-dev/topic/trace_in_gdb/90087736

内容如下: 问题: Is there a way to print out the trace for the packet buffer in gdb? For me VPP crashes when a packet goes wrongly to l2-input with RX interface without any l2 configuration. I'm using linux-cp and it looks like the packet doesn't hit the "linux-cp-xc-ip4" node for some reason. And what's strange is that it works for some time and only then crashes (so tracin the packet before crash doesn't help me at all). I want to see what node was before l2-input. 回答: Yes, you can call 'gdb_show_traces()' from gdb - but you'll need to have tracing enable beforehand of course. If that's not enough, you can enable trajectory tracing: https://git.fd.io/vpp/tree/src/vlib/buffer.h#n101 and inspect them via 'gdb_dump_trajectory_trace()'.

原来vpp专门给gdb增加可以调用的函数,可以通过cli show gdb查询,前面文章中有介绍gdb 快速查询vector结构体数据长度及vlib_buffer_t结构中opaque、opaque2都给出了快捷的方式。相当给力!

DBGvpp# show gdb 
vl(p) returns vec_len(p)
vb(b) returns vnet_buffer(b) [opaque]
vb2(b) returns vnet_buffer2(b) [opaque2]
vbi(b) returns b index
vgb(bi) returns vlib_get_buffer(vlib_get_main(), bi)
pe(p) returns pool_elts(p)
ph(p) returns pool_header(p)
pifi(p, i) returns pool_is_free_index(p, i)
gdb_show_errors(0|1) dumps error counters
gdb_show_session dumps session counters
gdb_show_traces() dumps buffer traces
gdb_validate_buffer(b) check vlib_buffer b sanity
debug_hex_bytes (ptr, n_bytes) dumps n_bytes in hex
vlib_dump_frame_ownership() does what it says
vlib_runtime_index_to_node_name (index) prints NN

下面是在环境中开启宏VLIB_BUFFER_TRACE_TRAJECTORY,通过buffer索引来回去经过的node节点。

#通过show trace 查询到buffer索引为:0xa53c6,查询经过node节点。
(gdb) call gdb_dump_trajectory_trace(0xa53c6)
Context trace for bi 676806 b 0x100294f180, visited 10
ethernet-input (669)
ip4-input-no-checksum (603)
ip4-lookup (620)
ip4-receive (617)
ip4-icmp-input (624)
ip4-icmp-echo-request (65)
ip4-load-balance (619)
ip4-rewrite (615)
GigabitEthernet2/2/0-output (696)
GigabitEthernet2/2/0-tx (695)
#通过buffer 索引得到vlib_buffer_t地址
(gdb) call vgb(0xa53c6)
$1 = (vlib_buffer_t *) 0x100294f180
#dump buffer内容,這裏還可以優化一下,打印出報文内容。
(gdb) call gdb_dump_buffer(0x100294f180)
current data 0, length 110, buffer-pool 0, ref-count 1, trace handle 0x1000000
ext-hdr-valid 
local l2-hdr-offset 0 l3-hdr-offset 14 
(gdb)