intel dpdk api makefile 编译选项修改 和 gdb 调试

来源:互联网 发布:unix 安装 软件 编辑:程序博客网 时间:2024/05/17 23:42

声明:此文档只做学习交流使用,请勿用作其他商业用途

author:朝阳_tony
E-mail : linzhaolover@gmail.com
Create Date: 2013-8-6 17:07:56 Tuesday
Last Change: 2013-8-6 18:47:51 Tuesday

转载请注明出处:http://blog.csdn.net/linzhaolover


此文请结合intel dpdk源码去阅读,源码可以去http://dpdk.org/dev 网页中下载;更多官方文档请访问http://dpdk.org

intel DPDK交流群希望大家加入互相学习,QQ群号:289784125


本文章基于intel dpdk  的源码1.3.1 版本进行讲解;


参考文档  “gcc警告选项”  http://blog.csdn.net/onlyou930/article/details/6553800


摘要

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.mkexec-env  rte.extapp.mk  rte.extvars.mk       rte.install.mk  rte.sdkbuild.mk    rte.sdkgcov.mk     rte.sdktest.mk     targetinternal  rte.extlib.mk  rte.gnuconfigure.mk  rte.lib.mk      rte.sdkconfig.mk   rte.sdkinstall.mk  rte.shared.mk      toolchainmachine   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-prototypesWERROR_FLAGS += -Wmissing-declarations -Wold-style-definition -Wpointer-arithWERROR_FLAGS += -Wcast-align -Wnested-externs -Wcast-qualWERROR_FLAGS += -Wformat-nonliteral -Wformat-security

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


2、dpdk编译优化选项设置

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

# binary nameAPP = l2fwd# all source are stored in SRCS-ySRCS-y := main.cCFLAGS += -O3CFLAGS += $(WERROR_FLAGS)

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

main.c 是l2fwd程序的源码;

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

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


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

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

1)、设置环境变量

export RTE_SDK=`pwd`export RTE_TARGET=x86_64-default-linuxapp-gccexport 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/l2fwdGNU 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) l593594             /* 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;600601             /* 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 595Breakpoint 1 at 0x40f420: file /home/linzhao/repo/dpdk_project/dpdk/examples/l2fwd/main.c, line 595.(gdb) b 602Breakpoint 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 3Starting 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:595595             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) srte_eal_init (argc=8, argv=0x7fffffffe248) at /home/linzhao/repo/dpdk_project/dpdk/lib/librte_eal/linuxapp/eal/eal.c:809809             struct shared_driver *solib = NULL;(gdb) s811             if (!rte_atomic32_test_and_set(&run_once))(gdb) srte_atomic32_test_and_set (v=0x6c0c40) at /home/linzhao/repo/dpdk_project/dpdk/x86_64-default-linuxapp-gcc/include/arch/rte_atomic.h:641641             return rte_atomic32_cmpset((volatile uint32_t *)&v->cnt, 0, 1);
从跟踪的信息看到,我们已经进入了dpdk/lib/librte_eal/linuxapp/eal/eal.c文件中,进行代码调试工作;

技术水平有待提高,如果文章有错误的地方希望读者指正,相互交流,互相学习;O(∩_∩)O~