RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Ubuntu 16.04系統(tǒng)中調(diào)試Apollo項(xiàng)目核心轉(zhuǎn)儲(chǔ)文件的方法

電子工程師 ? 來(lái)源:未知 ? 作者:李倩 ? 2018-03-23 09:30 ? 次閱讀

Linux系統(tǒng)中,若程序異常終止,操作系統(tǒng)會(huì)將程序當(dāng)時(shí)的內(nèi)存狀態(tài)記錄下來(lái),保存在一個(gè)文件中,這種行為叫做Core Dump(中文一般譯為“核心轉(zhuǎn)儲(chǔ)”)。實(shí)際上,除內(nèi)存信息之外,核心轉(zhuǎn)儲(chǔ)還會(huì)記錄程序的一些關(guān)鍵運(yùn)行狀態(tài),例如寄存器信息(包括程序指針、棧指針等)、內(nèi)存管理信息等。核心轉(zhuǎn)儲(chǔ)對(duì)于程序員調(diào)試程序非常有益,因?yàn)橛行┏绦蝈e(cuò)誤是很難重現(xiàn)的,例如指針異常,而核心轉(zhuǎn)儲(chǔ)文件可以重現(xiàn)程序出錯(cuò)時(shí)的情景。

1

Ubuntu 16.04系統(tǒng)中打開核心轉(zhuǎn)儲(chǔ)功能

Ubuntu 16.04系統(tǒng)默認(rèn)關(guān)閉了核心轉(zhuǎn)儲(chǔ)功能,需重新設(shè)置打開。

1檢查核心轉(zhuǎn)儲(chǔ)是否打開

按快捷鍵“Ctrl+Alt+T”打開命令終端,輸入命令:

ulimit -c

若輸出的結(jié)果為 0,則說(shuō)明默認(rèn)是關(guān)閉核心轉(zhuǎn)儲(chǔ)功能的,即當(dāng)程序異常終止時(shí),不會(huì)生成核心轉(zhuǎn)儲(chǔ)文件。

2在當(dāng)前命令終端中打開核心轉(zhuǎn)儲(chǔ)

使用命令:

ulimit -c unlimited

可開啟當(dāng)前命令終端的核心轉(zhuǎn)儲(chǔ)功能,并且不限制核心轉(zhuǎn)儲(chǔ)文件大??; 若需限制文件大小,將unlimited修改為你所需文件的大小,注意單位為KB。

3永久打開核心轉(zhuǎn)儲(chǔ)

若想永久打開核心轉(zhuǎn)儲(chǔ)功能,則使用命令:

sudo vi /etc/security/limits.conf

修改配置文件(我這里是使用vi編輯器修改,你可以換成自己熟悉的編輯器,但建議修改配置文件還是采用vi較好,因?yàn)樗撬蠻nix/Linux系統(tǒng)標(biāo)配的編輯器,并且簡(jiǎn)單的操作并不困難),增加如下所示的一行內(nèi)容:

#Each line describes a limit for a user in the form:## * soft core unlimited

4配置核心轉(zhuǎn)儲(chǔ)文件名是否添加PID號(hào)

默認(rèn)的核心轉(zhuǎn)儲(chǔ)文件名稱為core。通過(guò)修改/proc/sys/kernel/core_uses_pid文件可以讓生成的core文件名是否自動(dòng)加上pid號(hào)。使用命令:

sudo vi /proc/sys/kernel/core_uses_pid

將/proc/sys/kernel/core_uses_pid文件里的“0”修改為“1”,然后保存退出,這樣生成的core文件名將會(huì)變成core.pid,其中pid表示該進(jìn)程的PID。

5配置核心轉(zhuǎn)儲(chǔ)文件的生成位置及文件名格式

默認(rèn)的核心轉(zhuǎn)儲(chǔ)文件保存在可執(zhí)行文件所在的目錄下,可以通過(guò)修改/proc/sys/kernel/core_pattern文件來(lái)控制core文件的生成位置以及文件名格式。使用命令:

sudo vi /proc/sys/kernel/core_pattern

可對(duì)core文件的生成位置以及文件名格式進(jìn)行配置,以下是幾種配置示例:

# 示例1:將生成的core文件保存在/apollo/data/core目錄下,# 文件名格式:“core_進(jìn)程名.進(jìn)程PID”/apollo/data/core/core_%e.%p# 示例2:將生成的core文件保存在/tmp/core目錄下,# 文件名格式:“core_進(jìn)程名_進(jìn)程PID.時(shí)間戳”/tmp/core/core_%e_%p.%t# 示例3:這是Ubuntu默認(rèn)的core文件生成方式。# “apport”是一個(gè)用python寫的腳本程序,# 其作用是在可執(zhí)行文件目錄下生成core文件,# %p %s %c %d %P分別表示: # [global pid]/usr/share/apport/apport %p %s %c %d %P

注意:以上示例只能使用其中一個(gè),關(guān)于core文件的詳細(xì)命名格式,可以通過(guò)man core命令查看。

2

Ubuntu 16.04系統(tǒng)中調(diào)試核心轉(zhuǎn)儲(chǔ)文件的一個(gè)示例

1生成核心轉(zhuǎn)儲(chǔ)文件

首先撰寫一個(gè)C++測(cè)試程序,代碼如下:

#include int main(){ // Attention! // The following code will cause a core dump file. double *pointer; *pointer = 10; return 0;}

Linux系統(tǒng)中使用GCC編譯器的編譯命令如下:

g++ -g -Wall -std=c++11 *.cpp -o test

注意,上述命令一定要加“-g”選項(xiàng),生成調(diào)試信息,否則后面使用GDB調(diào)試核心轉(zhuǎn)儲(chǔ)文件時(shí),仍然無(wú)法定位程序崩潰點(diǎn)。

運(yùn)行該程序:

./test

輸出結(jié)果為:

段錯(cuò)誤 (核心已轉(zhuǎn)儲(chǔ))

ls -l的結(jié)果如下(我使用示例3所示的core文件生成方式):

總用量 584-rw------- 1 davidhopper davidhopper 565248 Mar 19 17:49 core-rw-rw-r-- 1 davidhopper davidhopper 163 Mar 19 16:27 main.cpp-rwxrwxr-x 1 davidhopper davidhopper 25968 Mar 19 17:49 test

可見,已經(jīng)在當(dāng)前可執(zhí)行文件目錄中生成了一個(gè)核心轉(zhuǎn)儲(chǔ)文件:core

2使用GDB調(diào)試器調(diào)試core文件

借助GDB調(diào)試器,使用如下命令,可調(diào)試core文件:

gdb ./test core

輸出信息如下:

GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1Copyright (C) 2016 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later 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-linux-gnu".Type "show configuration" for configuration details.For bug reporting instructions, please see:.Find the GDB manual and other documentation resources online at:.For help, type "help".Type "apropos word" to search for commands related to "word"...Reading symbols from ./test...done.[New LWP 4340]Core was generated by `./test'.Program terminated with signal SIGSEGV, Segmentation fault.#0 0x00000000004006c6 in main () at main.cpp:88 *pointer = 10;(gdb)

可見,GDB調(diào)試器根據(jù)生成的core文件,已經(jīng)找到了程序崩潰點(diǎn)為原程序的第8行??吹竭@里,是不是感覺到了GDB調(diào)試核心轉(zhuǎn)儲(chǔ)文件的威力?

3

Ubuntu 16.04系統(tǒng)中調(diào)試Apollo項(xiàng)目核心轉(zhuǎn)儲(chǔ)文件的方法

由于Apollo項(xiàng)目是在Docker中運(yùn)行,因此不能直接在Ubuntu 16.04系統(tǒng)中直接生成核心轉(zhuǎn)儲(chǔ)文件并使用GDB對(duì)其進(jìn)行調(diào)試,所有的工作必須在Docker中完成。具體操作步驟如下:

1啟動(dòng)并進(jìn)入Apollo項(xiàng)目的Docker

# 進(jìn)入Apollo項(xiàng)目根目錄(我的路徑為:~/code/apollo,你需要修改為自己的路徑)cd ~/code/apollo# 啟動(dòng)Apollo項(xiàng)目的Docker(注意:2.0以上版本在后面加上一個(gè)“-C”選項(xiàng),# 表示從中國(guó)服務(wù)器拉取鏡像文件,以加快下載速度)bash docker/scripts/dev_start.sh# 進(jìn)入Dockerbash docker/scripts/dev_into.sh

2在Docker內(nèi)部檢查并設(shè)置核心轉(zhuǎn)儲(chǔ)功能

在Docker內(nèi)部,使用本文第一部分內(nèi)容檢查并設(shè)置核心轉(zhuǎn)儲(chǔ)功能。在我的機(jī)器上,使用ulimit -c命令檢查的結(jié)果為:unlimited,表明已打開核心轉(zhuǎn)儲(chǔ)功能。假如在你的Docker內(nèi)部發(fā)現(xiàn)未開啟核心轉(zhuǎn)儲(chǔ)功能,該怎么辦?那就按照本文第一部分內(nèi)容重新打開唄。

同樣在我的Docker內(nèi)部,使用命令:cat /proc/sys/kernel/core_pattern查看核心轉(zhuǎn)儲(chǔ)文件的生成位置及文件名格式,得到的結(jié)果為:/apollo/data/core/core_%e.%p,表明Docker內(nèi)部的核心轉(zhuǎn)儲(chǔ)文件被保存在/apollo/data/core目錄下,文件名格式:core_進(jìn)程名.進(jìn)程PID。當(dāng)然,你也可以按照本文第一部分內(nèi)容對(duì)核心轉(zhuǎn)儲(chǔ)文件的保存位置及文件名格式進(jìn)行定制。

3在Docker內(nèi)部調(diào)試各功能模塊生成的核心轉(zhuǎn)儲(chǔ)文件的方法

在Apollo項(xiàng)目Docker內(nèi)部,所有功能模塊的可執(zhí)行文件均被放置于/apollo/bazel-bin/modules。下面以規(guī)劃(Planning)模塊為例進(jìn)行說(shuō)明。

最近,我修改了規(guī)劃模塊內(nèi)部的RTKReplayPlanner類。在通過(guò)Dreamview調(diào)試規(guī)劃模塊時(shí),經(jīng)常發(fā)現(xiàn)該模塊莫名其妙地退出,看日志文件沒有任何可用信息,根據(jù)我的編程經(jīng)驗(yàn),這一定是我在某處的指針使用存在問(wèn)題,要么是引用了空指針,要么是指針越界,如此等等,不一而足。是時(shí)候讓核心轉(zhuǎn)儲(chǔ)文件發(fā)揮作用了。

我打開/apollo/data/core目錄,果然找到了規(guī)劃模塊崩潰時(shí)生成的核心轉(zhuǎn)儲(chǔ)文件:core_planning.695,于是立刻在Docker內(nèi)部(即使用bash docker/scripts/dev_into.sh命令進(jìn)入Docker后的命令行終端內(nèi)操作)借助GDB調(diào)試該文件,命令如下所示。注意:若需定位程序崩潰位置,必須在構(gòu)建Apollo項(xiàng)目時(shí),添加調(diào)試信息。也就是說(shuō),構(gòu)建命令不能使用“build_opt”或“build_opt_gpu”等優(yōu)化選項(xiàng),而應(yīng)使用“build”或“build_gpu”等帶調(diào)試信息的選項(xiàng)。

gdb /apollo/bazel-bin/modules/planning/planning /apollo/data/core/core_planning.695

調(diào)試結(jié)果如下:

GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1Copyright (C) 2014 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later 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-linux-gnu".Type "show configuration" for configuration details.For bug reporting instructions, please see:.Find the GDB manual and other documentation resources online at:.For help, type "help".Type "apropos word" to search for commands related to "word"...Reading symbols from /apollo/bazel-bin/modules/planning/planning...done.[New LWP 747][New LWP 697][New LWP 695][New LWP 698][New LWP 709][New LWP 699][New LWP 714][New LWP 700][New LWP 746][New LWP 750][New LWP 749][New LWP 711][New LWP 702][New LWP 703][New LWP 704][New LWP 705][New LWP 706][New LWP 707][New LWP 708][New LWP 712][New LWP 745][New LWP 748][Thread debugging using libthread_db enabled]Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".Core was generated by `/apollo/bazel-bin/modules/planning/planning --flagfile=modules/planning/conf/pl'.Program terminated with signal SIGSEGV, Segmentation fault.#0 0x000000000042f476 in apollo::common::TrajectoryPoint::relative_time (this=0x0) at bazel-out/local-dbg/genfiles/modules/common/proto/pnc_point.pb.h:15141514 return relative_time_;(gdb)

上述結(jié)果表明,在bazel-out/local-dbg/genfiles/modules/common/proto/pnc_point.pb.h文件的1514行返回relative_time_時(shí),this指針為空,即引用了一個(gè)空指針。顯然,這里只是錯(cuò)誤暴露處,而非錯(cuò)誤產(chǎn)生處。聯(lián)想到我修改了RTKReplayPlanner類,于是我立即在modules/planning/planner/rtk/rtk_replay_planner.cc中查找關(guān)鍵字:relative_time,找到相關(guān)代碼處(注意:下面的代碼是我修改后的內(nèi)容,并非Apollo項(xiàng)目原有代碼):

// reset relative time double zero_time = current_trajectory[matched_index].relative_time(); for (auto& trajectory_point : trajectory_points) { // davidhopper // We shoud add the "planning_init_point.relative_time()" to // maintain the correct time sequence. trajectory_point.set_relative_time(trajectory_point.relative_time() - zero_time + planning_init_point.relative_time());

最終結(jié)果水落石出,原來(lái)是double zero_time = current_trajectory[matched_index].relative_time();作了越界引用。找到了錯(cuò)誤產(chǎn)生原因,代碼修改方法也就比較容易了,對(duì)matched_index的范圍作出限制即可解決問(wèn)題。

自Apollo平臺(tái)開放已來(lái),我們收到了大量開發(fā)者的咨詢和反饋,越來(lái)越多開發(fā)者基于Apollo擦出了更多的火花,并愿意將自己的成果貢獻(xiàn)出來(lái),這充分體現(xiàn)了Apollo『貢獻(xiàn)越多,獲得越多』的開源精神。為此我們開設(shè)了『開發(fā)者說(shuō)』板塊,希望開發(fā)者們能夠踴躍投稿,更好地為廣大自動(dòng)駕駛開發(fā)者營(yíng)造一個(gè)共享交流的平臺(tái)!

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11292

    瀏覽量

    209322
  • Ubuntu
    +關(guān)注

    關(guān)注

    5

    文章

    563

    瀏覽量

    29702
  • 編輯器
    +關(guān)注

    關(guān)注

    1

    文章

    805

    瀏覽量

    31163
  • Apollo
    +關(guān)注

    關(guān)注

    5

    文章

    342

    瀏覽量

    18443

原文標(biāo)題:開發(fā)者說(shuō) | 在Docker內(nèi)使用GDB調(diào)試Apollo項(xiàng)目的核心轉(zhuǎn)儲(chǔ)(Core Dump)文件

文章出處:【微信號(hào):Apollo_Developers,微信公眾號(hào):Apollo開發(fā)者社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Ubuntu 16.04 MATE樹莓派3版本開始支持板載Wi-Fi和藍(lán)牙

     Ubuntu的MATE項(xiàng)目負(fù)責(zé)人Martin Wimpress昨天宣布推出Ubuntu 16.04 MATE第二個(gè)Beta版本,Ubuntu
    發(fā)表于 04-06 10:20 ?4581次閱讀

    【BPI-M64試用體驗(yàn)】第一篇 燒寫ubuntu16.04 mate系統(tǒng)

    是沒有系統(tǒng)的,需要自己燒寫系統(tǒng),本人燒寫了ubuntu16.04mate與android6.0系統(tǒng)。需要準(zhǔn)備的工具有:220V轉(zhuǎn)5V電源,一
    發(fā)表于 04-17 08:51

    如何在VMware安裝ubuntu 16.04

    如何在VMware安裝ubuntu 16.04如何安裝Vitis AI幾個(gè)常見的docker指令
    發(fā)表于 02-24 06:24

    如何對(duì)Apollo2.5 CANBUS進(jìn)行全面調(diào)試?

    前言:CANBUS是Apollo需要根據(jù)你的底盤寫代碼的地方,感覺也是Apollo最難調(diào)試的部分。這部分首先要選好CAN卡,因?yàn)椴皇?b class='flag-5'>Apollo推薦的CAN卡,驅(qū)動(dòng)程序和對(duì)應(yīng)接口,可能
    發(fā)表于 08-30 06:02

    Ubuntu16.04配置開發(fā)編譯環(huán)境的過(guò)程是怎樣的?

    如何獲取Ubuntu16.04鏡像文件?Ubuntu16.04配置開發(fā)編譯環(huán)境的過(guò)程是怎樣的?
    發(fā)表于 03-04 07:06

    Ubuntu 16.04系統(tǒng)環(huán)境下Ubuntu固件的編譯流程是怎樣的

    Ubuntu 16.04系統(tǒng)環(huán)境下Ubuntu固件的編譯流程是怎樣的?如何在Ubuntu 16.04
    發(fā)表于 03-04 07:18

    如何使用Ubuntu 16.04編譯根文件系統(tǒng)

    如何使用Ubuntu 16.04編譯根文件系統(tǒng)?
    發(fā)表于 03-09 07:57

    移植Ubuntu16.04系統(tǒng)到ROC-RK3308-CC板子上記錄

    文件系統(tǒng)方法,最核心的地方就是通過(guò)交叉模擬器qemu-user-static,對(duì)文件系統(tǒng)進(jìn)行定制,這個(gè)大家按自己需求來(lái)就好,這里就不再贅述了,這里移植的是
    發(fā)表于 06-09 16:58

    有什么方法可以追溯地將加密標(biāo)志應(yīng)用于現(xiàn)有加密設(shè)備上的核心轉(zhuǎn)儲(chǔ)分區(qū)?

    我有一個(gè)生產(chǎn)固件的設(shè)備。我們啟用了閃存加密,并啟用了核心轉(zhuǎn)儲(chǔ)。不幸的是,我們沒有在文檔的任何地方看到核心
    發(fā)表于 03-02 08:01

    ubuntu隱藏/顯示文件文件

    ubuntu 16.04 LTS - 隱藏/顯示文件文件夾 1. GUI hot key Ctrl H: 隱藏/顯示文件
    發(fā)表于 11-25 12:52 ?5085次閱讀

    Ubuntu 16.04 MATE樹莓派3版本開始支持板載Wi-Fi和藍(lán)牙

    Ubuntu的MATE項(xiàng)目負(fù)責(zé)人Martin Wimpress今天宣布推出Ubuntu 16.04 MATE第二個(gè)Beta版本,Ub
    發(fā)表于 04-02 14:51 ?361次閱讀

    fireflyAIO-3288J主板編譯Ubuntu16.04固件簡(jiǎn)介

    編譯 Ubuntu16.04 固件(GPT) 前言 本 SDK 開發(fā)環(huán)境是在 Ubuntu 上開發(fā)測(cè)試的。我們推薦使用 Ubuntu 16.04
    的頭像 發(fā)表于 12-26 14:54 ?3265次閱讀
    fireflyAIO-3288J主板編譯<b class='flag-5'>Ubuntu16.04</b>固件簡(jiǎn)介

    嵌入式Linux移植3. NFS根文件系統(tǒng)掛載(從Ubuntu啟動(dòng)內(nèi)核,文件系統(tǒng)

    :通過(guò)tftp使用Ubuntu的/tftpboot的uImage啟動(dòng)rootfs根文件系統(tǒng):通過(guò)NFS使用Ubuntu
    發(fā)表于 11-02 12:51 ?7次下載
    嵌入式Linux移植3. NFS根<b class='flag-5'>文件系統(tǒng)</b>掛載(從<b class='flag-5'>Ubuntu</b>啟動(dòng)內(nèi)核,<b class='flag-5'>文件系統(tǒng)</b>)

    ubuntu與windows之間的文件互傳方法

    。因此在開發(fā)的過(guò)程中會(huì)經(jīng)常在 Windows和 Ubuntu兩者間切換,同時(shí)還需要頻繁的進(jìn)行文件互傳。一般情況下,ubuntu 與 windows 之間的文件互傳有如下三種
    的頭像 發(fā)表于 04-17 15:03 ?1.1w次閱讀
    <b class='flag-5'>ubuntu</b>與windows之間的<b class='flag-5'>文件</b>互傳<b class='flag-5'>方法</b>

    ubuntu刪除的文件怎么恢復(fù)

    Ubuntu系統(tǒng),刪除的文件可以通過(guò)多種方法進(jìn)行恢復(fù)。本文將詳細(xì)介紹Ubuntu
    的頭像 發(fā)表于 08-30 15:10 ?1392次閱讀
    RM新时代网站-首页