本文目錄一覽:
- 1、如何用vs code調試運行c語言程序
- 2、GDB ROS調試
- 3、gdb怎麼用
- 4、初步接觸linux,請問gdb調試start後載入動態庫符號時間很長,怎麼解決,可以不載入指定庫符號嗎?
- 5、GDB 調試命令
- 6、如何在Docker內部使用gdb調試器
如何用vs code調試運行c語言程序
VS Code雖然是個編輯器,但也能作為gdb的前端來啟動調試,實際調用的是gdb。
點擊VSCode左邊的「蟲子」圖標,然後點齒輪,就會讓你配置啟動調試json文件。
只要就是改一下啟動程序名,改為你要調試 的文件,保存。
在程序中點擊行號打上斷點,然後點擊「綠色的箭頭」就會啟動調試。
GDB ROS調試
ROS中用到第三方庫,在編譯第三方庫的時候,加上 -g 選項,以供調用該庫時調試。
在編譯ROS包的時候,使用如下命令編譯:
catkin_make -DCMAKE_BUILD_TYPE=Debug
GDB啟動應用
rosrun –prefix ‘gdb -ex run –args’ package node
之後就可以正常使用GDB命令來調試了,因為第三方庫編譯加了 -g 選項,所以可以進入調用庫中的函數進行調試。
gdb怎麼用
GDB調試,建議去下個系統的文檔;
GDB調試器
GCC用於編譯程序,而Linux的另一個GNU工具gdb則用於調試程序。gdb是一個用來調試C和C++程序的強力調試器,我們能通過它進行一系列調試工作,包括設置斷點、觀查變數、單步等。
其最常用的命令如下:
file:裝入想要調試的可執行文件。
kill:終止正在調試的程序。
list:列表顯示源代碼。
next:執行一行源代碼但不進入函數內部。
step:執行一行源代碼而且進入函數內部。
run:執行當前被調試的程序
quit:終止gdb
watch:監視一個變數的值
break:在代碼里設置斷點,程序執行到這?鍤憊移?
make:不退出gdb而重新產生可執行文件
shell:不離開gdb而執行shell
2)從你的描述上看來,你是用單獨的gdb.exe調試器,調試的時候不需要運行程序的,編譯的時候 只要加上相應的參數(」-g「)產生編譯後的可執行文件,
以gcc編譯sum.c(加-g選項產生debug信息):
gcc –g –o sum sum.c
在命令行上鍵入gdb sum並按回車鍵就可以開始調試sum了,再運行run命令執行sum。
初步接觸linux,請問gdb調試start後載入動態庫符號時間很長,怎麼解決,可以不載入指定庫符號嗎?
方法一、在/etc/ld.so.conf文件中添加路徑,vi /etc/ld.so.conf
添加下邊內容
123
include ld.so.conf.d/*.conf /usr/cluster/.share/lib
方法二、在終端輸入:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/cluster/.share/lib
方法三、修改/etc/profile文件
123
export MPI_HOME=/usr/cluster export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MPI_HOME/.share/lib
在終端執行source /etc/profile 使配置文件生效
程序運行時載入動態庫失敗的解決方法
錯誤提示如下:
error while loading shared libraries: libjson.so.0: cannot open shared object file: No such file or directory
原因一般有兩個,一個是操作系統中沒有包含該共享庫(lib*.so.* 文件)或者共享庫版本不對。解決辦法就是重新下載安裝。
另外一個原因就是已經安裝了該共享庫,但是執行需要調用該共享庫的程序的時候,程序按照默認共享庫路徑找不到該共享庫文件。解決方法如下:
如果共享庫文件安裝到了 /lib 或 /usr/lib 目錄下,那麼執行一下 ldconfig 命令。
ldconfig命令的用途, 主要是在默認搜尋目錄(b和/usrb)以及動態庫配置文件/etc/ld.so.conf內所列的目錄下, 搜索出可共享的動態鏈接庫(格式如lib*.so*), 進而創建出動態裝入程序(ld.so)所需的連接和緩存文件. 緩存文件默認為/etc/ld.so.cache, 此文件保存已排好序的動態鏈接庫名字列表.
如果共享庫文件安裝到了 /usr/local/lib (一般開源的共享庫都會安裝到該目錄下)或者其它非 /lib 或 /usr/lib 目錄下,那麼在執行 ldconfig 命令前,還要把新的共享庫目錄加入到共享庫配置文件 /etc/ld.so.conf 中,如下:
1234
# cat /etc/ld.so.confinclude ld.so.conf.d/*.conf# echo “/usr/local/lib” /etc/ld.so.conf# ldconfig
或者在 /etc/ld.so.conf.d/ 目錄下新建任何以 .conf 為後綴的文件,在該文件中加入庫文件所在的目錄。然後執行 ldconfig 更新 /etc/ld.so.cache 文件。
如果共享庫文件安裝到了其他非 /lib 或 /usr/lib 目錄下,但是又不想在 /etc/ld.so.conf 文件中加共享庫路徑(或者是沒有許可權加路徑)。那可以 export 一個全局變數 LD_LIBRARY_PATH,然後運行程序的時候就會去找個目錄中找共享庫。
LD_LIBRARY_PATH的意思是告訴loader在哪些目錄中可以找到共享庫. 可以設置多個搜索目錄, 這些目錄之間用冒號分隔開. 比如安裝了一個mysql到/usr/local/mysql目錄下, 其中有一大堆庫文件在/usr/local/mysql/lib下面, 則可以在.bashrc或.bash_profile或shell里加入以下語句即可:
export LD_LIBRARY_PATH=/usr/local/mysql/lib:$LD_LIBRARY_PATH
一般來講這只是一種臨時的解決方案, 在沒有許可權或臨時需要的時候使用.
如果程序需要的庫文件比系統目前存在的庫文件版本低,可以做一個鏈接。比如:
12345
error while loading shared libraries: libncurses.so.4: cannot open sharedobject file: No such file or directoryls /usr/lib/libncu*/usr/lib/libncurses.a /usr/lib/libncurses.so.5/usr/lib/libncurses.so /usr/lib/libncurses.so.5.3
可見雖然沒有libncurses.so.4,但有libncurses.so.5,是可以向下兼容的
建一個鏈接就好了
1
ln -s /usr/lib/libncurses.so.5.3 /usr/lib/libncurses.so.4
GDB 調試命令
(gdb) i r
(gdb) i r a # 查看所有寄存器(包括浮點、多媒體)
(gdb) i r esp
(gdb) i r pc
(gdb) x /wx 0x80040000 # 以16進位顯示指定地址處的數據
(gdb) x /8x esp+12
(gdb) x /16s 0x86468700 # 以字元串形式顯示指定地址處的數據
(gdb) x /24i 0x8048a51 # 以指令形式顯示指定地址處的數據(24條)
(gdb) set $v0 = 0x004000000
(gdb) set $epc = 0xbfc00000
(gdb) set {unsigned int}0x8048a51=0x0
(gdb) set (unsigned int )0x8048a54=0x55aa55aa
Usage: find start end count value
(gdb) b *0x80400000
(gdb) watch *(unsigned int *)0xbffff400==0x90909090
更多
如何在Docker內部使用gdb調試器
前幾天一個小夥伴發郵件問我,他在docker內部使用gdb調試時刻遇到了gdb如下報錯信息
ptrace:Operation not permitted
當時我的答覆是在docker create或者docker run時刻開啟 萬精油–privileged參數 。小夥伴的問題就此解決了。
但是事實並非如此簡單
Docker借用了linux對進程設置capabilities,而其子進程繼承父進程capabilites特性來完成對容器capacities的控制。Docker create和docker run參數中有下面兩個參數可以對容器默認的capabilites進行修改:
–cap-add //添加某個capabilites屬性 –cap-del //剔除某個默認的capabilites屬性
cap-add和cap-del可以設置的參數可以通過下面鏈接查詢到:
但是這並不是問題的全部,對於上述測試程序,如果執行下面命令gdb又有告警出來
雖然依然可以調試,但是我們還是需要搞清楚上述告警的意思。地址隨機化是linux一項安全特性,它允許內核進程啟動每次載入庫的時候都在隨機化的分布在進程虛擬內存地址空間上(早期固定的庫要載入到固定地方,如果固定地方被佔用才載入到別地方。會造成多次載入程序,其庫地址都不變。如此有安全隱患)。在gdb調試中gdb默認需要關閉linux的地址隨機化功能,可以通過gdb 命令set disable-randomization off關閉。 如果在地址隨機化下調試同一段程序,多次run時候可以看到它的運行地址和函數地址不一致,這沒有什麼太大的問題。問題可以結束一半了
關於gdb 設置地址隨機化開關詳情見下面鏈接:
當然上述告警其實也可以不通過gdb設置來完成,可以通過下面介紹的Docker參數可以達成。
Docker默認情況下為每個容器都設置了一個默認的seccom profile。一般情況下無需修改。但是docker依然支持
docker create或者docker run時候通過–security-opt seccomp=xxx參數來設置docker容器的seccomp策略。
xxx可以是一個json格式文件,裡面定義了docker容器每個具體的seccomp規則。也可以是字元unconfined表示關閉默認的docker seccomp 規則。
可以通過下面命令徹底關閉docker默認seccomp引入的任何限制
docker run -it –security-opt seccomp=unconfined centos:lastes
在運行上述gdb 調試命令run一個進程,告警信息終於徹底消失了。
Docker設置的seccomp 默認profile規則可以通過如下鏈接查詢到:
本文就不再做詳細展開了。
從Linux 2.6.23開始支持這種特性對進程能夠使用的系統調用進行控制,如此可以進行一些安全性策略。sandbox就是依賴於此技術。docker梳理了Linux的系統調用,從300+個系統調用中屏蔽掉了44個系統調用,但是又最大程度的不影響正常的應用使用系統。
從Linux 2.1開始支持的特性,將超級用戶的許可權劃分為多個組,每個進程都有一個capabilities屬性,子進程從自己的父進程中基礎capacities。這個特性和sudo不一樣,因為sudo控制粒度太粗;而capabilities控制粒度很精細。linux有一系列的調用可以設置、查看,清除和比較進程的capabilities。可以通過:
man cap_set_flag
來查看這一系列的系統調用。而具體進程的capacities可以通過/proc/$pid/status中:
Capxxx欄位看到,本文就不再展開。感興趣的朋友可以參考
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/195778.html