热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用gdb调试多进程和多线程的服务器程序

转自:http:bbs.chinaunix.netviewthread.php?tid1609486&page3&authorid20701329
转自: http://bbs.chinaunix.net/viewthread.php?tid=1609486&page=3&authorid=20701329
1发表于 2009-11-06 15:17 | 显示全部帖子

 

刚好这几天用gdb调试多进程和多线程的服务器程序,以往对于这类程序也都是打日志加core文件的方法,
但逻辑过于复杂的时候,屡次增加日志终是不爽,对于一般的服务器程序去掉编译优化选项gdb跟踪还是很好的,
对于多进程和多线程的daemon后台程序, set follow-fork-mode 或者attache的方式也一样可以直接跟出问题。

 

2发表于 2009-11-07 23:04 | 显示全部帖子

 

QUOTE:
原帖由 benjiam 于 2009-11-7 13:06 发表
刚好这几天用gdb调试多进程和多线程的服务器程序,以往对于这类程序也 ...




来个直观的,echosvc是个多进程并使用多线程的daemon服务器程序:


QUOTE:
$ ls
config.ini  echosvc  log.txt  runtest.sh
$ gdb echosvc
GNU gdb 6.8-debian
Copyright (C) 2008 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 "i486-linux-gnu"...
(gdb) l
95                }
96       
97                apr_pollset_add(cs->pollset,cs->pfd);
98                return 0;
99        }
100       
101        int main(int argc,const char * const argv[])
102        {
103       
104                if(zevent_init(file,&pglobal)==-1)
(gdb) set follow-fork-mode child
(gdb) b zevent_process_connection
Breakpoint 1 at 0x80489b2: file echo.c, line 34.
(gdb) r
Starting program: echosvc
[Thread debugging using libthread_db enabled]
[Thread debugging using libthread_db enabled]
[New Thread 0xb7ce08d0 (LWP 8755)]
[Thread debugging using libthread_db enabled]
[New Thread 0xb7ce08d0 (LWP 8756)]
[New Thread 0xb637ab90 (LWP 8757)]
[New Thread 0xb5b79b90 (LWP 875 ]
[New Thread 0xb5378b90 (LWP 8759)]
[New Thread 0xb4b77b90 (LWP 8760)]
[New Thread 0xb4376b90 (LWP 8761)]
[New Thread 0xb3b75b90 (LWP 8762)]
[New Thread 0xb3374b90 (LWP 8763)]
[New Thread 0xb2b73b90 (LWP 8764)]
[New Thread 0xb2372b90 (LWP 8765)]
[New Thread 0xb1b71b90 (LWP 8766)]
[New Thread 0xb1370b90 (LWP 8767)]
[New Thread 0xb0b6fb90 (LWP 876 ]
[New Thread 0xb036eb90 (LWP 8769)]
[New Thread 0xafb6db90 (LWP 8770)]
[New Thread 0xaf36cb90 (LWP 8771)]
[New Thread 0xaeb6bb90 (LWP 8772)]
[New Thread 0xae36ab90 (LWP 8773)]
[New Thread 0xadb69b90 (LWP 8774)]
[tcsetpgrp failed in terminal_inferior: No such process]
[Thread 0xb637ab90 (LWP 8757) exited]
[Switching to Thread 0xae36ab90 (LWP 8773)]

Breakpoint 1, zevent_process_connection (cs=0x832cc40) at echo.c:34 当客户端发送消息成功进入断点函数
34                apr_size_t len=0;
(gdb) l
29                /*
30                 * code for your app,this just an example for echo test.
31                 */
32                apr_bucket *b;
33                char *msg;
34                apr_size_t len=0;
35                int olen = 0;
36                const char *buf;
37                apr_status_t rv;
38       
(gdb)
39                cs->pfd->reqevents = APR_POLLIN;
40       
41                if(cs->pfd->rtnevents & APR_POLLIN){
42                        len = 4096;
43                        msg = (char *)apr_bucket_alloc(len,cs->baout);
44                        if (msg == NULL) {
45                                return -1;
46                        }
47                        rv = apr_socket_recv(cs->pfd->desc.s,msg,&len);
48                        if(rv != APR_SUCCESS)
(gdb) b 47 想看看我到底收到了什么
Breakpoint 2 at 0x8048a13: file echo.c, line 47.
(gdb) c
Continuing.

Breakpoint 2, zevent_process_connection (cs=0x832cc40) at echo.c:47
47                        rv = apr_socket_recv(cs->pfd->desc.s,msg,&len);
(gdb) n
48                        if(rv != APR_SUCCESS)
(gdb) p msg
$1 = 0x8332a78 "asdf/r/n"   
(gdb) info threads
  19 Thread 0xadb69b90 (LWP 8774)  0xb7f2a430 in __kernel_vsyscall ()
* 18 Thread 0xae36ab90 (LWP 8773)  zevent_process_connection (cs=0x832cc40) at echo.c:48 我们正在调试的线程
  17 Thread 0xaeb6bb90 (LWP 8772)  0xb7f2a430 in __kernel_vsyscall ()
  16 Thread 0xaf36cb90 (LWP 8771)  0xb7f2a430 in __kernel_vsyscall ()
  15 Thread 0xafb6db90 (LWP 8770)  0xb7f2a430 in __kernel_vsyscall ()
  14 Thread 0xb036eb90 (LWP 8769)  0xb7f2a430 in __kernel_vsyscall ()
  13 Thread 0xb0b6fb90 (LWP 876   0xb7f2a430 in __kernel_vsyscall ()
  12 Thread 0xb1370b90 (LWP 8767)  0xb7f2a430 in __kernel_vsyscall ()
  11 Thread 0xb1b71b90 (LWP 8766)  0xb7f2a430 in __kernel_vsyscall ()
  10 Thread 0xb2372b90 (LWP 8765)  0xb7f2a430 in __kernel_vsyscall ()
  9 Thread 0xb2b73b90 (LWP 8764)  0xb7f2a430 in __kernel_vsyscall ()
  8 Thread 0xb3374b90 (LWP 8763)  0xb7f2a430 in __kernel_vsyscall ()
  7 Thread 0xb3b75b90 (LWP 8762)  0xb7f2a430 in __kernel_vsyscall ()
  6 Thread 0xb4376b90 (LWP 8761)  0xb7f2a430 in __kernel_vsyscall ()
  5 Thread 0xb4b77b90 (LWP 8760)  0xb7f2a430 in __kernel_vsyscall ()
  4 Thread 0xb5378b90 (LWP 8759)  0xb7f2a430 in __kernel_vsyscall ()
  3 Thread 0xb5b79b90 (LWP 875   0xb7f2a430 in __kernel_vsyscall ()
  1 Thread 0xb7ce08d0 (LWP 8756)  0xb7f2a430 in __kernel_vsyscall ()
(gdb) bt
#0  zevent_process_connection (cs=0x832cc40) at echo.c:48
#1  0xb7f2457c in zevent_run_process_connection (cs=0x832cc40) at zevent_hooks.c:14
#2  0xb7f20aef in process_socket (p=0x832ca50, sock=0x832ca90, cs=0x832cc40, my_child_num=0, my_thread_num=15)
    at zevent.c:401
#3  0xb7f2145b in worker_thread (thd=0x8305f38, dummy=0x8307b5 at zevent.c:788
#4  0xb7f13736 in dummy_worker (opaque=0x8305f3 at threadproc/unix/thread.c:142
#5  0xb7d0f4ff in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#6  0xb7e4149e in clone () from /lib/tls/i686/cmov/libc.so.6
(gdb)




进程结构,类似如下:

QUOTE:
$ pstree -p 9788
echosvc(978 ───echosvc(9789)─┬─{echosvc}(9791)
                              ├─{echosvc}(9792)
                              ├─{echosvc}(9793)
                              ├─{echosvc}(9794)
                              ├─{echosvc}(9795)
                              ├─{echosvc}(9796)
                              ├─{echosvc}(9797)
                              ├─{echosvc}(979
                              ├─{echosvc}(9799)
                              ├─{echosvc}(9800)
                              ├─{echosvc}(9801)
                              ├─{echosvc}(9802)
                              ├─{echosvc}(9803)
                              ├─{echosvc}(9804)
                              ├─{echosvc}(9805)
                              ├─{echosvc}(9806)
                              └─{echosvc}(9807)



对于多个工作进程下图的情况则需要使用attach的方式,熟练后都不会太麻烦。
下面这种结构比较少见 但nginx和apache的event的模式下就是这种结构:

QUOTE:
echosvc(9894)─┬─echosvc(9895)─┬─{echosvc}(9897)
              │               ├─{echosvc}(989
              │               ├─{echosvc}(9907)
              │               ├─{echosvc}(990
              │               ├─{echosvc}(9909)
              │               └─{echosvc}(9910)
              ├─echosvc(9899)─┬─{echosvc}(9901)
              │               ├─{echosvc}(9902)
              │               ├─{echosvc}(9903)
              │               ├─{echosvc}(9904)
              │               ├─{echosvc}(9905)
              │               └─{echosvc}(9906)
              ├─echosvc(9911)─┬─{echosvc}(9913)
              │               ├─{echosvc}(9914)
              │               ├─{echosvc}(9915)
              │               ├─{echosvc}(9916)
              │               ├─{echosvc}(9917)
              │               └─{echosvc}(9918)
              ├─echosvc(9919)─┬─{echosvc}(9921)
              │               ├─{echosvc}(9922)
              │               ├─{echosvc}(9923)
              │               ├─{echosvc}(9924)
              │               ├─{echosvc}(9925)
              │               └─{echosvc}(9926)
              ├─echosvc(9927)─┬─{echosvc}(9929)
              │               ├─{echosvc}(9932)
              │               ├─{echosvc}(9933)
              │               ├─{echosvc}(9934)
              │               ├─{echosvc}(9935)

 

上面的多数派观点真浪费了贴出详细例子的苦心,本想再贴些技巧,算拉。
我觉得某个为平台开发软件熟悉这个平台的基本编辑,开发,调试环境是基本能力,
如果程序出现问题 需要紧急现场调试开发 这时候你的环境不会有vc,log可能没有记下意外,
看到很多老手在紧急情况下艰难的编辑修改代码,就像刚学打字步履维艰 很着急,
稍花点时间让自己专业一点不行吗,所谓艺不压身,很多行业的开发特点不一样 ,尤其是很多行业软件环境,
不是你想什么环境甲方就会给你,从事互联网开发方面的问题比较突出,或许因为环境比较宽容,也就更
疏于这方面的技能。

[ 本帖最后由 zhoubug 于 2009-11-11 17:40 编辑 ]

推荐阅读
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • centos 7.0 lnmp成功安装过程(很乱)
    下载nginx[rootlocalhostsrc]#wgethttp:nginx.orgdownloadnginx-1.7.9.tar.gz--2015-01-2412:55:2 ... [详细]
  • 在将Web服务器和MySQL服务器分离的情况下,是否需要在Web服务器上安装MySQL?如果安装了MySQL,如何解决PHP连接MySQL服务器时出现的连接失败问题? ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 本文为初学者提供了一条清晰的学习路线,帮助他们逐步成长为优秀的Web开发人员。通过十个关键步骤,涵盖从基础到高级的各个方面,确保每位学习者都能找到适合自己的学习方向。 ... [详细]
  • vsftpd配置(虚拟用户、匿名用户登录)
    一、ftp服务搭建(一)概述1.ftp连接及传输模式(1)控制连接TCP21,用于发送FTP命令信息 ... [详细]
  • Ubuntu 22.04 安装搜狗输入法详细指南及常见问题解决方案
    本文将详细介绍如何在 Ubuntu 22.04 上安装搜狗输入法,并提供常见问题的解决方法。包括下载安装包、更新源、安装依赖项等步骤。 ... [详细]
  • PHP 5.5.31 和 PHP 5.6.17 安全更新发布
    PHP 5.5.31 和 PHP 5.6.17 已正式发布,主要包含多个安全修复。强烈建议所有用户尽快升级至最新版本以确保系统安全。 ... [详细]
  • 通过将常用的外部命令集成到VSCode中,可以提高开发效率。本文介绍如何在VSCode中配置和使用自定义的外部命令,从而简化命令执行过程。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 本文详细探讨了Oracle数据库中Number和Float数据类型的特性和使用方法。通过对比分析,解释了Number类型在精度和范围上的优势,以及Float类型在处理科学计算时的灵活性。文章还介绍了Number数据类型的语法结构及其在实际应用中的最佳实践,帮助读者更好地理解和选择合适的数据类型以满足不同的业务需求。 ... [详细]
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • 在 Linux 环境下,多线程编程是实现高效并发处理的重要技术。本文通过具体的实战案例,详细分析了多线程编程的关键技术和常见问题。文章首先介绍了多线程的基本概念和创建方法,然后通过实例代码展示了如何使用 pthreads 库进行线程同步和通信。此外,还探讨了多线程程序中的性能优化技巧和调试方法,为开发者提供了宝贵的实践经验。 ... [详细]
author-avatar
uigrdg更好_154
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有