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

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