分类 技术志 下的文章

用GDB调试多进程程序

有一段时间没有写技术方面的东西了^_^。众所周知,GDB是Unix/Linux下调试程序的龙头老大,GDB功能强大,我们在平时多使用其一些最基本的功能,而且一般调试的都是单进程的程序。最近一个项目中的问题让我接触如何使用GDB调试多进程程序,更确切的是说调试调用fork的多进程程序。

使用GDB最好的文档就是其名为'Debugging with GDB'的参考手册。手册中有一小章节提到了如何调试多进程程序。一般情况下,如果被gdb调试的程序中调用fork派生出一个新的子进程,这时gdb调试的仍然还是父进程,其子进程的执行不被理会。如果之前你在子进程的执行routine上设置了断点,那么当子进程执行到那个断点时,子进程会因为收到一个SIGTRAP信号而自行终止,除非你在子进程中拦截了该信号。

那么使用GDB该如何调试多进程程序呢?在其参考手册中提供了一种通用方法,这里说说(GDB在某些平台上如HP-UX,还提供了更简便的方法,不过不具备通用性,这里不说):

[测试程序]
我们先看看我们的测试程序:
/* in eg1.c */

int wib(int no1, int no2)
{
        int result, diff;
        diff = no1 – no2;
        result = no1 / diff;
        return result;
}

int main()
{
        pid_t   pid;

        pid = fork();
        if (pid <0) {
                printf("fork err\n");
                exit(-1);
        } else if (pid == 0) {
                /* in child process */
                sleep(60); —————— (!)

                int     value   = 10;
                int     div     = 6;
                int     total   = 0;
                int     i       = 0;
                int     result  = 0;

                for (i = 0; i < 10; i++) {
                        result = wib(value, div);
                        total += result;
                        div++;
                        value–;
                }

                printf("%d wibed by %d equals %d\n", value, div, total);
                exit(0);
        } else {
                /* in parent process */
                sleep(4);
                wait(-1);
                exit(0);
        }
}
该测试程序中子进程运行过程中会在wib函数中出现一个'除0'异常。现在我们就要调试该子进程。

[调试原理]
不知道大家发现没有,在(!)处在我们的测试程序在父进程fork后,子进程调用sleep睡了60秒。这就是关键,这个sleep本来是不该存在于子进程代码中的,而是而了使用GDB调试后加入的,它是我们调试的一个关键点。为什么要让子进程刚刚运行就开始sleep呢?因为我们要在子进程睡眠期间,利用shell命令获取其process id,然后再利用gdb调试外部进程的方法attach到该process id上,调试该进程。

[调试过程]
我觉上面的调试原理的思路已经很清晰了,剩下的就是如何操作的问题了。我们来实践一次吧!
我所使用的环境是Solaris OS 9.0/GCC 3.2/GDB 6.1。

GDB调试程序的前提条件就是你编译程序时必须加入调试符号信息,即使用'-g'编译选项。首先编译我们的源程序'gcc -g -o eg1 eg1.c'。编译好之后,我们就有了我们的调试目标eg1。由于我们在调试过程中需要多个工具配合,所以你最好多打开几个终端窗口,另外一点需要注意的是最好在eg1的working directory下执行gdb程序,否则gdb回提示'No symbol table is loaded'。你还得手工load symbol table。好了,下面我们就'按部就班'的开始调试我们的eg1。

执行eg1:
eg1 &   — 让eg1后台运行吧。

查找进程id:
ps -fu YOUR_USER_NAME

运行gdb:
gdb
(gdb) attach xxxxx  — xxxxx为利用ps命令获得的子进程process id
(gdb) stop — 这点很重要,你需要先暂停那个子进程,然后设置一些断点和一些Watch
(gdb) break 37 — 在result = wib(value, div);这行设置一个断点,可以使用list命令察看源代码
Breakpoint 1 at 0×10808: file eg1.c, line 37.
(gdb) continue
Continuing.

Breakpoint 1, main () at eg1.c:37
37                              result = wib(value, div);
(gdb) step
wib (no1=10, no2=6) at eg1.c:13
13              diff = no1 – no2;
(gdb) continue
Continuing.

Breakpoint 1, main () at eg1.c:37
37                              result = wib(value, div);
(gdb) step
wib (no1=9, no2=7) at eg1.c:13
13              diff = no1 – no2;
(gdb) continue
Continuing.

Breakpoint 1, main () at eg1.c:37
37                              result = wib(value, div);
(gdb) step
wib (no1=8, no2=8) at eg1.c:13
13              diff = no1 – no2;
(gdb) next
14              result = no1 / diff;
(gdb) print diff
$6 = 0        ——- 除数为0,我们找到罪魁祸首了。
(gdb) next
Program received signal SIGFPE, Arithmetic exception.
0xff29d830 in .div () from /usr/lib/libc.so.1

至此,我们调试完毕。

上面仅仅是一个简单的多进程程序,在我们平时开发的多进程程序远远比这个复杂,但是调试基本原理是不变,有一些技巧则需要我们在实践中慢慢摸索。

Hacker Culture摘要

最近看了Eric S. Raymond的被称为开源文化圣典的'Cathedral and Bazaar'(大教堂与市集)以及他的另外一篇文章'How To Become A Hacker',必须承认的是我不能够完全理解其中的内容,因为没有体验,或者说我还不够资格对Hacker Culture高谈阔论,所以这里仅作部分摘要,并说说自己第一时间的感受,望日后能温故知新。

在开始了解Hacker Culture之前我们应该知道'什么是Hacker'。Hacker不同于Cracker,前者指那些热衷于计算机技术,水平高超的电脑专家,他们把通过自己的实践而获得的知识广泛传播;而后者则尤指那些为了个人利益利用计算机技术搞非法破坏的人。像我们耳熟能详的Hacker先驱包括开源软件运动的发起人Richard M. Stallman、Unix之父Ken Thompson、C语言的发明人之一的Dennis Ritchie、Linux之父Linus Torvalds以及Eric S. Raymond等等。我相信这些人才是从事计算机行业的人们心目中真正的'Hero'。

'Cathedral and Bazaar'可谓是开源世界对Hacker Culture的一个阶段性的小结,当然Hacker Culture还在进化,其内容也在不断的丰富当中。下面是从'Cathedral and Bazaar'摘录的一些我觉得能够代表Hacker Culture的语句:

1.Every good work of software starts by scratching a developer's personal itch.
这里有一个生僻词itch,这个词有'发痒'、'渴望'的意思。这句可理解为“每个好的软件工作都开始于满足开发者个人的渴望或为开发者个人'抓痒'”。Unix的起缘可以很好地证明这一点。而现在的大多数商业软件的开发者则不能归为此类,原因不讲自明。

2. Good programmers know what to write. Great ones know what to rewrite (and reuse).
Linus之所以能独立完成一个操作系统内核,很大原因是因为他没有'从头开始',而是利用已有的优秀设计思想。

3. When you lose interest in a program, your last duty to it is to hand it off to a competent successor.
Hacker也要'能上能下'。^_^

4. Treating your users as co-developers is your least-hassle route to rapid code improvement and effective debugging.
把用户当作协作开发者。

5. Release Early, Release Often
这与4相辅相成,互利互惠。Linux已经展现给我们一个Best实践,其“早发布、常发布策略”的一个效果就是利用快速的传播反馈修订来使重复劳动达到最小。

6. Smart data structures and dumb code works a lot better than the other way around.
优秀的数据结构设计总是至关重要的,在平时的开发中这一点体会破深。Brooks曾幽默地说:"Show me your [code] and conceal your [data structures], and I shall continue to be mystified. Show me your [data structures], and I won’t usually need your [code]; it'll be obvious."

7. Often, the most striking and innovative solutions come from realizing that your concept of the problem was wrong.
当你认识到你对问题的理解是错误的,这时不要灰心,因为一个具有革新性的解决方案也许正摆在你的眼前,我想很多人都有过类似的经历,Me,too。

8. "Perfection (in design) is achieved not when there is nothing more to add, but rather when there is nothing more to take away."
是不是颠覆了你以前对好的设计的理解了呢?

9. To solve an interesting problem, start by finding a problem that is interesting to you.
趣之所在,力之所在。

10. Software is developed for peer recognition not for money.
至高无上的境界,不为'铜臭'打工。

这里再列出一条,这是在一位同行给Eric的回复中提到的一条:"杀掉一个项目最快的方法是在你什么都还没有之前就宣布它,我已经见的太多了,尤其是在Linux世界里",看到这一条相信很多曾组织或参与开源项目的人都会深刻的体会到,Me , too。

中国程序员在开源软件世界中的地位大家也都略知一二,我想这或多或少都与我们对Hacker Culture的理解有关。理解和认同'Hacker Culture'是你进入开源世界的第一步,正所谓思想的融入才是真正的融入。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats