日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

为什么在Docker里使用gdb调试器会报错

發(fā)布時(shí)間:2025/3/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么在Docker里使用gdb调试器会报错 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景

前幾天一個(gè)小伙伴發(fā)郵件問(wèn)我,他在docker內(nèi)部使用gdb調(diào)試時(shí)刻遇到了gdb如下報(bào)錯(cuò)信息
ptrace:Operation not permitted
當(dāng)時(shí)我的答復(fù)是在docker create或者docker run時(shí)刻開(kāi)啟萬(wàn)精油--privileged參數(shù)。小伙伴的問(wèn)題就此解決了。
但是事實(shí)并非如此簡(jiǎn)單

Docker上涉及到gdb調(diào)試權(quán)限的特性

capabilities

Docker借用了linux對(duì)進(jìn)程設(shè)置capabilities,而其子進(jìn)程繼承父進(jìn)程capabilites特性來(lái)完成對(duì)容器capacities的控制。Docker create和docker run參數(shù)中有下面兩個(gè)參數(shù)可以對(duì)容器默認(rèn)的capabilites進(jìn)行修改:
--cap-add //添加某個(gè)capabilites屬性 --cap-del //剔除某個(gè)默認(rèn)的capabilites屬性
cap-add和cap-del可以設(shè)置的參數(shù)可以通過(guò)下面鏈接查詢到:
https://docs.docker.com/engine/reference/commandline/run/

  • Docker 將gdb調(diào)試需要SYS_PTRACE屬性被禁止掉了,所以gdb在調(diào)試的時(shí)候會(huì)顯示ptrace被禁止。所以想在docker內(nèi)部調(diào)試gdb解決辦法就是create和run的時(shí)候帶上--cap-add sys_ptrace*
    例如:
docker run -it --cap-add sys_ptrace centos:latest /bin/bash root@7f5a2130e975>cd /home/ root@7fa2130e975> vi test.c \#include <stdio.h> int main(){int i = 0;printf(“Testing begin\n”);While(1){printf(“Loop cnt:%d\n”,i++);sleep(10); }}root@7fa2130975>gcc -c -g -o test.o test.c root@7fa2130975>gcc -o test -g test.o root@7fa2130975>./test& [1] 18 root@7fa2130975>gdb attach 18 //ok可以調(diào)試了

但是這并不是問(wèn)題的全部,對(duì)于上述測(cè)試程序,如果執(zhí)行下面命令gdb又有告警出來(lái)

root@7fa2130975>gdb ./test (gdb) r Warning:Error disabling address space randomization:Operation not permitted

雖然依然可以調(diào)試,但是我們還是需要搞清楚上述告警的意思。地址隨機(jī)化是linux一項(xiàng)安全特性,它允許內(nèi)核進(jìn)程啟動(dòng)每次加載庫(kù)的時(shí)候都在隨機(jī)化的分布在進(jìn)程虛擬內(nèi)存地址空間上(早期固定的庫(kù)要加載到固定地方,如果固定地方被占用才加載到別地方。會(huì)造成多次加載程序,其庫(kù)地址都不變。如此有安全隱患)。在gdb調(diào)試中g(shù)db默認(rèn)需要關(guān)閉linux的地址隨機(jī)化功能,可以通過(guò)gdb 命令set disable-randomization off關(guān)閉。如果在地址隨機(jī)化下調(diào)試同一段程序,多次run時(shí)候可以看到它的運(yùn)行地址和函數(shù)地址不一致,這沒(méi)有什么太大的問(wèn)題。問(wèn)題可以結(jié)束了
關(guān)于gdb 設(shè)置地址隨機(jī)化開(kāi)關(guān)詳情見(jiàn)下面鏈接:
http://visualgdb.com/gdbreference/commands/set_disable-randomization
當(dāng)然上述告警其實(shí)也可以不通過(guò)gdb設(shè)置來(lái)完成,可以通過(guò)下面介紹的Docker參數(shù)可以達(dá)成。

seccomp

Docker默認(rèn)情況下為每個(gè)容器都設(shè)置了一個(gè)默認(rèn)的seccom profile。一般情況下無(wú)需修改。但是docker依然支持
docker create或者docker run時(shí)候通過(guò)--security-opt seccomp=xxx參數(shù)來(lái)設(shè)置docker容器的seccomp策略。
xxx可以是一個(gè)json格式文件,里面定義了docker容器每個(gè)具體的seccomp規(guī)則。也可以是字符unconfined表示關(guān)閉默認(rèn)的docker seccomp 規(guī)則。
可以通過(guò)下面命令徹底關(guān)閉docker默認(rèn)seccomp引入的任何限制
docker run -it --security-opt seccomp=unconfined centos:lastes
在運(yùn)行上述gdb 調(diào)試命令run一個(gè)進(jìn)程,告警信息終于徹底消失了。
Docker設(shè)置的seccomp 默認(rèn)profile規(guī)則可以通過(guò)如下鏈接查詢到:
https://docs.docker.com/engine/security/seccomp/
本文就不再做詳細(xì)展開(kāi)了。

Docker背后的實(shí)現(xiàn)技術(shù)

Docker實(shí)現(xiàn)seccomp控制

從Linux 2.6.23開(kāi)始支持這種特性對(duì)進(jìn)程能夠使用的系統(tǒng)調(diào)用進(jìn)行控制,如此可以進(jìn)行一些安全性策略。sandbox就是依賴于此技術(shù)。docker梳理了Linux的系統(tǒng)調(diào)用,從300+個(gè)系統(tǒng)調(diào)用中屏蔽掉了44個(gè)系統(tǒng)調(diào)用,但是又最大程度的不影響正常的應(yīng)用使用系統(tǒng)。

  • 在Docker engine上有一個(gè)叫seccomp模塊提供了為docker提供默認(rèn)seccomp規(guī)則(GetDefaultProfile()函數(shù)),而我們?cè)诿钚信渲玫膕eccomp屬性會(huì)覆蓋默認(rèn)的seccomp規(guī)則(在setSeccomp()函數(shù)里)。最終規(guī)則在engine內(nèi)部創(chuàng)建runc spec時(shí)刻函數(shù)createSpec生產(chǎn)。將seccomp傳遞到oci runtime spec的spec.linux.seccomp字段里。
  • 而runc通過(guò)seccomp庫(kù)的InitSeccomp()函數(shù),在Init一個(gè)容器時(shí)刻和exec觸發(fā)的將一個(gè)進(jìn)程setns到容器內(nèi)部時(shí)刻調(diào)用此函數(shù) 將seccomp屬性設(shè)置到容器的init進(jìn)程或者exec進(jìn)程里。
  • Linux進(jìn)程屬性里有seccomp屬性,此屬性也會(huì)父子繼承,通過(guò)/proc/$pid/status里可以看到進(jìn)程的seccomp屬性。

Docker實(shí)現(xiàn)capabilities

從Linux 2.1開(kāi)始支持的特性,將超級(jí)用戶的權(quán)限劃分為多個(gè)組,每個(gè)進(jìn)程都有一個(gè)capabilities屬性,子進(jìn)程從自己的父進(jìn)程中基礎(chǔ)capacities。這個(gè)特性和sudo不一樣,因?yàn)閟udo控制粒度太粗;而capabilities控制粒度很精細(xì)。linux有一系列的調(diào)用可以設(shè)置、查看,清除和比較進(jìn)程的capabilities。可以通過(guò):
man cap_set_flag
來(lái)查看這一系列的系統(tǒng)調(diào)用。而具體進(jìn)程的capacities可以通過(guò)/proc/$pid/status中:
Capxxx字段看到,本文就不再展開(kāi)。感興趣的朋友可以參考
https://www.cnblogs.com/iamfy/archive/2012/09/20/2694977.html

  • 在oci runtime spec里規(guī)定了spec.Process.Capabilities屬性。runc中finializeNamespace()根據(jù)此屬性對(duì)進(jìn)程的capabilities進(jìn)行設(shè)置。此函數(shù)會(huì)在init容器和exec加一個(gè)進(jìn)程到容器時(shí)刻調(diào)用。

總結(jié)

以上是生活随笔為你收集整理的为什么在Docker里使用gdb调试器会报错的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。