如何在docker中進行gdb調試

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

環境準備

install nsenter

nsenter 工具在 util-linux 包2.23版本後包含。 nsenter 可以訪問另一個進程的名字空間。nsenter 要正常工作需要有 root 許可權。 很不幸,Ubuntu 14.04 仍然使用的是 util-linux 2.20。

$ cd /tmp; curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-; cd util-linux-2.24;$ ./configure --without-ncurses$ make nsenter && sudo cp nsenter /usr/local/bin

pull ubuntu image

$ docker pull ubuntu

ubuntu:gdb鏡像製作

sources.list

啟動ubuntu鏡像的容器

$ docker run -it --rm ubuntu bashroot@27b0644624a9:/#

查看ubuntu版本:

root@27b0644624a9:/# cat /etc/issueUbuntu 16.04.1 LTS \n \l

因為容器裡還沒有vi等基礎軟體,所以在虛機上編輯sources.list:

deb http://mirrors.zte.com.cn/ubuntu/ xenial main multiverse restricted universedeb http://mirrors.zte.com.cn/ubuntu/ xenial-backports main multiverse restricted universedeb http://mirrors.zte.com.cn/ubuntu/ xenial-proposed main multiverse restricted universedeb http://mirrors.zte.com.cn/ubuntu/ xenial-security main multiverse restricted universedeb http://mirrors.zte.com.cn/ubuntu/ xenial-updates main multiverse restricted universedeb-src http://mirrors.zte.com.cn/ubuntu/ xenial main multiverse restricted universedeb-src http://mirrors.zte.com.cn/ubuntu/ xenial-backports main multiverse restricted universedeb-src http://mirrors.zte.com.cn/ubuntu/ xenial-proposed main multiverse restricted universedeb-src http://mirrors.zte.com.cn/ubuntu/ xenial-security main multiverse restricted universedeb-src http://mirrors.zte.com.cn/ubuntu/ xenial-updates main multiverse restricted universe

拷貝sources.list到容器的/etc/apt/目錄下:

$ docker cp ./sources.list 27:/etc/apt/

install some software for gdb

更新源的索引:

root@27b0644624a9:/# apt-get update

gdb依賴python的3.x版本。在ubuntu14.04中,gdb依賴的python版本是3.4,那麼在ubuntu16.04中,gdb依賴的python版本應該不低於3.4。
搜尋一下python3.x版本的程式名:

root@27b0644624a9:/# apt-cache search python

安裝python:

root@27b0644624a9:/# apt-get install python3

查詢python版本號碼,符合預期:

root@27b0644624a9:/# python3 --versionPython 3.5.2

安裝gdb:

root@27b0644624a9:/# apt-get install gdb

驗證gdb是否可以run:

root@27b0644624a9:/# gdbGNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1Copyright (C) 2016 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-linux-gnu".Type "show configuration" for configuration details.For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.For help, type "help".Type "apropos word" to search for commands related to "word".(gdb)

vi是很基礎的編輯工具,也建議安裝:

root@27b0644624a9:/# apt-get install vim

save ubuntu:gdb image

$ docker commit 27 ubuntu:gdb$ docker save -o ubuntu-gdb.tar ubuntu:gdb

ubuntu:gdb鏡像驗證

Dockerfile

Benchmark是筆者用C++開發的一個關於網路效能的測試載入器,它同時支援linux socket和dpdk socket,所以對dpdk的動態庫有依賴。
Dockerfile檔案描述:

FROM ubuntu:gdbCOPY ./libdpdk.so /lib/COPY ./Benchmark /BenchmarkENTRYPOINT ["/Benchmark"]

製作鏡像:

$ docker build -t ubuntu-gdb:test .$ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED              SIZEubuntu-gdb          test                10f840213452        About a minute ago   294 MB

run image

$ docker run -it --rm ubuntu-gdb:test bashis dpdk 0self ip is 0self port is 10008socket fd is 3msgReceive: now begin receive msg!

查看容器Id:

$ docker psCONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMESfd97fcd35a67        ubuntu-gdb:test     "/Benchmark bash"   About a minute ago   Up About a minute                       priceless_bell

進入容器:

$ docker exec -it fd bashroot@fd97fcd35a67:/#

gdb debug

查看進程號:

root@fd97fcd35a67:/# ps auxUSER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMANDroot         1 46.7  0.0  33016  1964 ?        Ssl+ 10:00   7:17 /Benchmark bashroot         7  0.0  0.0  18244  3340 ?        Ss   10:08   0:00 bashroot        18  0.0  0.0  34424  2912 ?        R+   10:16   0:00 ps aux

查看該容器對應的Pid:

$ docker inspect -f {{.State.Pid}} fd15099

先輸入nsenter命令使gdb attach成功,然後再分別輸入info threads和bt命令確認響應沒毛病:

$  sudo nsenter -t 15099 -m -p gdb -p 1[sudo] password for zte: GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1Copyright (C) 2016 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-linux-gnu".Type "show configuration" for configuration details.For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.For help, type "help".Type "apropos word" to search for commands related to "word".Attaching to process 1[New LWP 6][Thread debugging using libthread_db enabled]Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".0x00007fc7f369298d in pthread_join () from /lib/x86_64-linux-gnu/libpthread.so.0(gdb) info threads  Id   Target Id         Frame* 1    Thread 0x7fc7f41b1940 (LWP 1) "Benchmark" 0x00007fc7f369298d in pthread_join () from /lib/x86_64-linux-gnu/libpthread.so.0  2    Thread 0x7fc7f281b700 (LWP 6) "Benchmark" 0x00007fc7f369a8f3 in recvfrom () from /lib/x86_64-linux-gnu/libpthread.so.0(gdb) bt#0  0x00007fc7f369298d in pthread_join () from /lib/x86_64-linux-gnu/libpthread.so.0#1  0x0000000000407e57 in main (argc=2, argv=0x7fffe3029a08) at /home/zte/gitlab/benchmark/src/Main.cpp:135(gdb)

應用情境

gdb調試一般是不得已的選擇。我們一般先是通過代碼走查和測試來找bug,其次是通過日誌分析找bug,最後的最後才是通過gdb找bug。話雖如此,但gdb調試仍然很重要,比如程式“卡死”等情境。
每個應用程式容器都依賴gdb並不是能在容器中進行gdb調試的唯一選擇。在有kubernetes叢集的系統中,gdb所在的容器可以在一個pod中掛一個,當出現“頑疾”時通過共用檔案系統來偵錯工具。

小結

本文以ubuntu系統為例,先介紹了環境準備,然後帶著讀者一起製作了ubuntu:gdb鏡像,最後以C++程式為例驗證了ubuntu:gdb鏡像的可用性。本文所講的對於docker的gdb調試方法具有一定的通用性,大家可以在其他的linux系統上如法炮製,同時支援gdb調試的語言都可以通過本文介紹的方法在docker中調試,比如Golang,它和C/C++的gdb調試稍有不同,具體請參考官方文檔《Debugging Go Code with GDB》。在虛擬化時代,掌握docker中的gdb調試方法是一個程式員的基本技能之一。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.