如何在docker中进行gdb调试

环境准备

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 bash
root@27b0644624a9:/# 

查看ubuntu版本:

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

因为容器里还没有vi等基础软件,所以在虚机上编辑sources.list:

deb http://mirrors.zte.com.cn/ubuntu/ xenial main multiverse restricted universe
deb http://mirrors.zte.com.cn/ubuntu/ xenial-backports main multiverse restricted universe
deb http://mirrors.zte.com.cn/ubuntu/ xenial-proposed main multiverse restricted universe
deb http://mirrors.zte.com.cn/ubuntu/ xenial-security main multiverse restricted universe
deb http://mirrors.zte.com.cn/ubuntu/ xenial-updates main multiverse restricted universe
deb-src http://mirrors.zte.com.cn/ubuntu/ xenial main multiverse restricted universe
deb-src http://mirrors.zte.com.cn/ubuntu/ xenial-backports main multiverse restricted universe
deb-src http://mirrors.zte.com.cn/ubuntu/ xenial-proposed main multiverse restricted universe
deb-src http://mirrors.zte.com.cn/ubuntu/ xenial-security main multiverse restricted universe
deb-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 --version
Python 3.5.2

安装gdb:

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

验证gdb是否可以run:

root@27b0644624a9:/# gdb
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (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:gdb

COPY ./libdpdk.so /lib/
COPY ./Benchmark /Benchmark

ENTRYPOINT ["/Benchmark"]

制作镜像:

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

run image

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

查看容器Id:

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
fd97fcd35a67        ubuntu-gdb:test     "/Benchmark bash"   About a minute ago   Up About a minute                       priceless_bell

进入容器:

$ docker exec -it fd bash
root@fd97fcd35a67:/#

gdb debug

查看进程号:

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

查看该容器对应的Pid:

$ docker inspect -f {{.State.Pid}} fd
15099

先输入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.1
Copyright (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调试方法是一个程序员的基本技能之一。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容

  • Docker — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
    ahohoho阅读 15,499评论 15 147
  • docker基本概念 1. Image Definition 镜像 Image 就是一堆只读层 read-only...
    慢清尘阅读 8,720评论 1 21
  • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
    极客圈阅读 10,468评论 0 120
  • 五、Docker 端口映射 无论如何,这些 ip 是基于本地系统的并且容器的端口非本地主机是访问不到的。此外,除了...
    R_X阅读 1,730评论 0 7
  • 虽然还是经常和妈妈吵来吵去 越来越发现身边的老人家,她越来越老去,你陪伴的时间也越来越有限 想一起做得事情,越来越...
    Kiko627阅读 175评论 0 0