用gdb调试找出nginx崩溃的原因

标签: gdb 调试 nginx | 发表时间:2013-03-18 10:07 | 作者:[email protected] (鲁塔弗)
出处:http://lutaf.com

某年某月某日,一个工程师跑来找我说:很多用户抱怨APP频繁闪退,他觉得server运行正常,找不出原因,请我帮忙

按照流程一路排查下去,发现nginx访问日志里面有大量的http 504 err code

tail -f /var/log/messages

同时出现大量的类似错误信息

nginx[1234]: segfault at 0000000000000008 rip 000000000043edf8 rsp 00007fff34a21fa0 error 4

出现segfault那只能用gdb了,这也是Linux做server的好处了,换成微软平台,无比的麻烦

解决问题分成4步:

  1. 配置系统生成coredump文件,很简单

    ulimit -a

    第一行就是关于core file的设置,默认是不生成coredump文件的,执行 ulimit -c 1024 即可,记得调试完成之后要用 ulimit -c 0关闭,不然你的硬盘很快会被填满

  2. gdb调试,需要debug版本的nginx才能定位到源代码,于是需要重新编译一份nginx

    首先把现有的nginx bin目录和conf目录都备份

    然后打印nginx的原始编译选项

    /opt/nginx/sbin/nginx -V

    在这个基础上加上 --with-debug,重新make一份即可

    在${NGINX-SOURCE-DIR}$/objs 目录中找到编译好的nginx ,复制到你的nginx运行目录,切记不要make install ,因为这样会覆盖掉你的nginx.conf文件

  3. 重新运行nginx,等待core.xxx文件生成。一般是在当前目录下生成

  4. 用gdb加载 coredump 文件

    gdb --core=core.xxx

    gdb> where

很容易就找到了nginx segfault的原因:我们自己写的一个nginx modules里面,对某些参数没有做边界检查,但外部环境变化之后,访问空指针了

收尾:

  • ulimit -c 0 :关掉coredump

  • 改完代码之后,重新编译一份不带debug信息的nginx

相关 [gdb 调试 nginx] 推荐:

nginx源码分析--GDB调试

- - CSDN博客架构设计推荐文章
利用gdb[i]调试nginx[ii]和利用gdb调试其它程序没有两样,不过nginx可以是daemon程序,也可以以多进程运行,因此利用gdb调试和平常会有些许不一样. 当然,我们可以选择将nginx设置为非daemon模式并以单进程运行,而这需做如下设置即可:. master_process off; 这是第一种情况:.

用gdb调试找出nginx崩溃的原因

- - 鲁塔弗的博客
某年某月某日,一个工程师跑来找我说:很多用户抱怨APP频繁闪退,他觉得server运行正常,找不出原因,请我帮忙. 按照流程一路排查下去,发现nginx访问日志里面有大量的http 504 err code. 同时出现大量的类似错误信息. 出现segfault那只能用gdb了,这也是Linux做server的好处了,换成微软平台,无比的麻烦.

gdb调试工具

- - CSDN博客系统运维推荐文章
查看帮助一是man 命令,二是进入 www.gnu.org,找到gdb的帮助文档(更详细). gcc -Wall -g main.c -o main,只有这样才能产生调试信息,包括core的调试信息.     run(r)  运行,执行到断点,重新用r,表示重新开始执行.     list(l)  列出源代码,l 2,l main,l 2,16(数字表示行数).

Linux下gdb调试

- - CSDN博客移动开发推荐文章
关于gdb的其他客套话不多说,直接进入正题. 列出产生执行文件源代码的一部分. 执行一行源代码但不进入函数内部. 执行一行源代码而且进入函数内部. 监视一个变量的值,一旦值有变化程序停住. 1.新建一个源文件vi yrp.cc,源代码如下:. 2.生成可执行文件 g++ -g -o yrp yrp.cc  注意必须使用-g参数,编译会加入调试信息,否则无法调试执行文件..

[转]GDB调试多线程

- - 小彰
GDB 多线程调试基本命令 实现简介 以及一个问题的解决. 一直对GDB多线程调试接触不多,最近因为工作有了一些接触,简单作点记录吧. 先介绍一下GDB多线程调试的基本命令. 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID. 切换当前调试的线程为指定ID的线程.

Linux下进行GDB调试

- - CSDN博客推荐文章
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具. 一般来说,GDB主要帮助自己完成下面四个方面的功能;. 1:启动你的程序,可以按照你的自定义的要求随心所欲的运行程序. 2:可以让被调试的程序在你所指定的调制的断点处停住(断点可以是条件表达式). 3:当程序被停住时,可以检查你的程序中发生的事.

GDB学习之道:GDB调试精粹及使用实例

- - CSDN博客系统运维推荐文章
要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出说明符(<和>)和外壳通配符(*、. 如果你使用不带参数的run命令,gdb就再次使用你给予前一条run命令的参数,这是很有用的. 利用set args 命令就可以修改发送给程序的参数,而使用show args 命令就可以查看其缺省参数的列表.

使用 gdb 调试 Python 进程

- yinseny - python.cn(jobs, news)
有时我们会想调试一个正在运行的Python进程,或者一个Python进程的coredump. 例如现在遇到一个mod_wsgi的进程僵死了,不接受请求,想看看究竟是运行到哪行Python代码呢. 这时就需要祭出gdb这个神器了. 确认你的gdb版本是>=7,gdb从版本7开始支持对Python的debug.

用gdb+nm调试php c extension程序

- ndv - 淘宝核心系统团队博客
最近在写Beanstalkd的php c extension客户端程序,写程序离不开调试,下面把调试中碰到的问题和解决方法和大家分享一下. .so写好了是给php脚本调用的,如果php脚本执行崩掉了,.so也只能在进程中饮恨而终,这时候php脚本调试经常用的echo, print_r, var_dump都派不上用场了.

GDB调试精粹及使用实例

- - CSDN博客推荐文章
当出现EXE_BAD_ACCESS, SIGABRT 及其他Crash时可以尝试用:. 要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出说明符(<和>)和外壳通配符(*、. 如果你使用不带参数的run命令,gdb就再次使用你给予前一条run命令的参数,这是很有用的.