DPDK之makefile编译选项修改和gdb调试

摘要

intel dpdk 的makefile 写的很好,该好好学习他的这种架构,但在调试程序时候发现,它的编译选项优化级别很高;怎样去修改intel dpdk中的编译选项,达到自己一个一个满意的程度;其大部分makefile规则都定义在dpdk/mk目录下;最后再说一下怎样用gdb工具调试dpdk;

# ls mk/
arch      rte.app.mk     rte.extshared.mk     rte.hostlib.mk  rte.obj.mk         rte.sdkdoc.mk      rte.sdktestall.mk  rte.vars.mk
exec-env  rte.extapp.mk  rte.extvars.mk       rte.install.mk  rte.sdkbuild.mk    rte.sdkgcov.mk     rte.sdktest.mk     target
internal  rte.extlib.mk  rte.gnuconfigure.mk  rte.lib.mk      rte.sdkconfig.mk   rte.sdkinstall.mk  rte.shared.mk      toolchain
machine   rte.extobj.mk  rte.hostapp.mk       rte.module.mk   rte.sdkdepdirs.mk  rte.sdkroot.mk     rte.subdir.mk

常见问题及解决方法

1、报错:defined but not used

为了测试程序,肯定会有一些变量临时注释掉,或者有些变量定义了,但没有赋值,有些函数定义了,但不去调用;可是dpdk在编译的时候,只要有错误警告就会编译退出;

解决方法:

vim mk/toolchain/gcc/rte.vars.mk

打开mk/toolchain/gcc/rte.vars.mk文件,其中有这几行

WERROR_FLAGS := -W -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
WERROR_FLAGS += -Wmissing-declarations -Wold-style-definition -Wpointer-arith
WERROR_FLAGS += -Wcast-align -Wnested-externs -Wcast-qual
WERROR_FLAGS += -Wformat-nonliteral -Wformat-security

第一行中的-Werror 选项就是指在gcc编译的时候,有任何错误就停止编译,直接退出,将这个选项去掉就可以只报警告,除非真有错误退出了;

2、dpdk编译优化选项设置

以dpdk/examples/l2fwd/Makefile文件为例

# binary name
APP = l2fwd
 
# all source are stored in SRCS-y
SRCS-y := main.c
 
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)

2fwd 是指编译出来的可执行程序名称;

main.c 是l2fwd程序的源码;

-O3 是只gcc的编译优化选项,如果不想优化基本这么高,可以将其改为 -O0、-O1 、-O2 等等 ;

CFLAGS += $(WERROR_FLAGS) 如果把这一行去的,就是去掉所有的编译警告选项,易可以达到在1部分写的去除编译警告退出的目的,但这就有点过了,有点警告才能知道自己的程序哪有问题;

3、dpdk 添加调试选项方便调试程序

有时候我们想用gdb调试我们的程序,应该怎样添加编译选项呢

1)设置环境变量

export RTE_SDK=`pwd`
export RTE_TARGET=x86_64-default-linuxapp-gcc
export EXTRA_CFLAGS="-O0 -g"

在dpdk目录,设置一下上面的环境变量,其实主要是为了设置makefile用到的编译选项EXTRA_CFLAGS 将其优化级别设置为 -O0 , 还有gdb的调试选项 -g;

2)然后编译

make -C x86_64-default-linuxapp-gcc/
make -C examples/l2fwd/

我测试的是l2fwd这个实例程序,其他实例程序编译大同小异;

3)用gdb运行测试程序

执行 gdb examples/l2fwd/build/l2fwd 运行测试程序;

# gdb examples/l2fwd/build/l2fwd
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-50.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/linzhao/repo/dpdk_project/dpdk/examples/l2fwd/build/l2fwd...done.
(gdb)

你可能会想,在执行程序的时候不是要输入程序的所需要的参数吗,不用急,在运行的时候在输入参数就行;

在gdb中执行 l 这个命令,就是list 的第一字母执行显示,看一下程序;在哪儿打断点比较好;

(gdb) l
593
594             /* init EAL */
595             ret = rte_eal_init(argc, argv);
596             if (ret < 0)
597                     rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
598             argc -= ret;
599             argv += ret;
600
601             /* parse application arguments (after the EAL ones) */
602             ret = l2fwd_parse_args(argc, argv);

我试着在 595行和602行大断点,分别在运行时进入这两个子函数,rte_eal_init是dpdk的库函数;l2fwd_parse_args是l2fwd 程序的私有函数;

用b ,break的第一字母打断点;

(gdb) b 595
Breakpoint 1 at 0x40f420: file /home/linzhao/repo/dpdk_project/dpdk/examples/l2fwd/main.c, line 595.
(gdb) b 602
Breakpoint 2 at 0x40f461: file /home/linzhao/repo/dpdk_project/dpdk/examples/l2fwd/main.c, line 602.

运行程序,在gdb中执行运行命令 r ,就是run的第一个字母;

注意我传入的参数, -c 1f 是指定5个core, -n4 是四通道, -p 3 是用两个端口;

(gdb) r -c 1f -n 4 -- -p 3
Starting program: /home/linzhao/repo/dpdk_project/dpdk/examples/l2fwd/build/l2fwd -c 1f -n 4 -- -p 3
[Thread debugging using libthread_db enabled]
 
Breakpoint 1, main (argc=8, argv=0x7fffffffe248) at /home/linzhao/repo/dpdk_project/dpdk/examples/l2fwd/main.c:595
595             ret = rte_eal_init(argc, argv);
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.47.el6.x86_64

现在程序运行到了我第一个断点595行处,

然后执行单步运行命令s ,也是step的缩写;看是否能进入rte_eal_init程序运行;

(gdb) s
rte_eal_init (argc=8, argv=0x7fffffffe248) at /home/linzhao/repo/dpdk_project/dpdk/lib/librte_eal/linuxapp/eal/eal.c:809
809             struct shared_driver *solib = NULL;
(gdb) s
811             if (!rte_atomic32_test_and_set(&run_once))
(gdb) s
rte_atomic32_test_and_set (v=0x6c0c40) at /home/linzhao/repo/dpdk_project/dpdk/x86_64-default-linuxapp-gcc/include/arch/rte_atomic.h:641
641             return rte_atomic32_cmpset((volatile uint32_t *)&v->cnt, 0, 1);

从跟踪的信息看到,我们已经进入了dpdk/lib/librte_eal/linuxapp/eal/eal.c文件中,进行代码调试工作;

原文链接:https://blog.csdn.net/linzhaolover/article/details/9794285

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章