如何找出发生SEGV内存错误的程序

  • A+
Categories:Linux

有用户使用《lnmp一键安装包》在CentOS6.6 64bit上安装php(php5.4、Opcache、ZendGuardLoader)、hhvm,用vhost.sh添加虚拟主机选择php,使用某主题(主题加密,需要使用ZendGuardLoader),启用改主题直接报502错误。束手无策,于是找我来排错,如下:

通过查看php日志/usr/local/php/var/log/php-fpm.log,有如下警告信息:

  1. [16-Mar-2015 16:03:09] WARNING: [pool www] child 9453 exited on signal 11 (SIGSEGV) after 9.601040 seconds from start

日志中的信息表明,进程号为9453的进程由于收到SIGSEGV信号而退出了。收到这个信号的时候,程序是可以生成core文件的。不过通过日志我们可以知道进程9453退出时没有生成core文件。因为在php-fpm的日志中,如果退出时生成了core文件,日志中会有“SIGSEGV – core dumped”字样。如:

  1. [16-Mar-2015 16:04:29] WARNING: [pool www] child 9581 exited on signal 11 (SIGSEGV - core dumped) after 15.921916 seconds from start

core dump文件对于诊断Linux中程序的问题非常有用。当程序异常退出的时候,可能会生成core文件。如,程序写一个不属于他的内存,操作系统出于保护,会发信号给程序,程序可能会因此而退出,退出的时候可能会生成core文件。我们可以通过分析core文件,找出程序中那里有内存问题。这篇文章主要是阐述生成core文件需要做的一些设置。

如何生成core文件

默认Linux操作系统是不允许生成core文件的。如下:

  1. [root@linuxeye ~]# ulimit -a
  2. core file size          (blocks, -c) 0
  3. data seg size           (kbytes, -d) unlimited
  4. scheduling priority             (-e) 0
  5. file size               (blocks, -f) unlimited
  6. pending signals                 (-i) 5762
  7. max locked memory       (kbytes, -l) 64
  8. max memory size         (kbytes, -m) unlimited
  9. open files                      (-n) 65535
  10. pipe size            (512 bytes, -p) 8
  11. POSIX message queues     (bytes, -q) 819200
  12. real-time priority              (-r) 0
  13. stack size              (kbytes, -s) 10240
  14. cpu time               (seconds, -t) unlimited
  15. max user processes              (-u) 65535
  16. virtual memory          (kbytes, -v) unlimited
  17. file locks                      (-x) unlimited

可以通过如下命令解除限制:

  1. [root@linuxeye ~]# ulimit -c unlimited
  2. [root@linuxeye ~]# ulimit -a
  3. core file size          (blocks, -c) unlimited
  4. data seg size           (kbytes, -d) unlimited
  5. scheduling priority             (-e) 0
  6. file size               (blocks, -f) unlimited
  7. pending signals                 (-i) 5762
  8. max locked memory       (kbytes, -l) 64
  9. max memory size         (kbytes, -m) unlimited
  10. open files                      (-n) 65535
  11. pipe size            (512 bytes, -p) 8
  12. POSIX message queues     (bytes, -q) 819200
  13. real-time priority              (-r) 0
  14. stack size              (kbytes, -s) 10240
  15. cpu time               (seconds, -t) unlimited
  16. max user processes              (-u) 65535
  17. virtual memory          (kbytes, -v) unlimited
  18. file locks                      (-x) unlimited

注意,ulimit -c 的设置仅仅是对你完成设置后启动的进程有效。而且退出登陆后,再进入需要从新设置。否则从新登陆后启动的进程也无法生成core文件。

如果想永久生效,可以把命令加入到 /etc/profile 中。建议不要这样做, 会疯狂dump文件,浪费性能

如何找到core文件

一般情况下,core文件会生成在你执行程序的地方。文件名是core.进程号

你也可以指定core文件名和生成目录。在/etc/sysctl.conf 文件中指定

  1. # vi /etc/sysctl.conf
  2. kernel.core_uses_pid = 1 #追加进程号到core文件名中
  3. fs.suid_dumpable = 2 #确保设置属主的进程也可以生成core文件
  4. kernel.core_pattern = /tmp/core-%e-%s-%u-%g-%p-%t #指定core文件生成的位置和文件名规则。

文件名规则可以使用的参数有:

  1. %% – 符号%
  2. %p – 进程号
  3. %u – 进程用户id
  4. %g – 进程用户组id
  5. %s – 生成core文件时收到的信号
  6. %t – 生成core文件的 时间 (seconds since 0:00h, 1 Jan 1970)
  7. %h – 主机名
  8. %e – 程序文件名

执行如下命令,让设置生效


  1. # sysctl -p

重启php-fpm

  1. service php-fpm restart

重现502错误

访问http://demo.linuxeye.com/wp-admin/customize.php?theme=dux

日志/usr/local/php/var/log/php-fpm.log中会有"SIGSEGV – core dumped"字样

如何使用core文件

可以使用gdb命令查看core文件信息

  1. gdb -e /usr/local/php/sbin/php-fpm -c /tmp/core-php-fpm-11-501-501-9581-1426493066

根据上面的堆栈信息,可以知道Optimizer(即Opcache)有问题,编辑/usr/local/php/etc/php.ini,注销掉Opcache段,重启php-fpm ,正常。。。

参考:http://www.searchtb.com/2014/03/如何找出发生segv内存错误的程序.html

Tue Mar 17 10:35:26 CST 2015

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

Replies to:7   Visitors  6   Admin  1

    • avatar tomyqqq 2

      WordPress Version 4.3.2 + Centos6.4 + LNMP1.2 + PHP 5.4.41 + mysql 5.5.42 + Zend Opcache v7.0.2 + phpmyadmin-3.3.5.1 + webbench-1.5

      目前phpmyadmin这个版本所有的都可以正常操作,唯独不能 点【导出】那里, 当把opcache禁止了,就可以【导出】了。

      • avatar tomyqqq 2

        你好,我在云服务器上,装了 军哥的LNMP1.2 + Zend Opcache + phpmyadmin, 碰到了 后2者不能共存,要是 允许 Zend Opcache了,phpmyadmin就打不开了,只好禁止 Zend Opcache,请问这是什么原因? 谢谢。

          • avatar yeho Admin

            @tomyqqq PHP那个版本?

              • avatar tomyqqq 2

                @yeho WordPress Version 4.3.2 + Centos6.4 + LNMP1.2 + PHP 5.4.41 + mysql 5.5.42 + Zend Opcache v7.0.2 + phpmyadmin-3.3.5.1 + webbench-1.5
                目前phpmyadmin这个版本所有的都可以正常操作,唯独不能 点【导出】那里, 当把opcache禁止了,就可以【导出】了。

                • avatar tomyqqq 2

                  @yeho 你好, php-fpm.php 出现

                  [19-Jan-2016 16:12:28] WARNING: [pool www] child 26244 exited on signal 11 (SIGSEGV – core dumped) after 17.732217 seconds from start
                  [19-Jan-2016 16:12:28] NOTICE: [pool www] child 26249 started

                  但是 按上面配置了 sysctl.conf, 并没生成 /tmp/core-xxxxxx 文件,

                  • avatar tomyqqq 2

                    @yeho /var/log/messages出现

                    Jan 19 16:24:05 ebs-49300 kernel: php-fpm[26709]: segfault at 1868238 ip 0000000001868238 sp 00007fff4041c9b8 error 15

                    • avatar tomyqqq 2

                      @yeho 你好,
                      gdb后,如下

                      Loaded symbols for /lib64/libselinux.so.1
                      Reading symbols from /usr/local/zend/ZendGuardLoader.so…Missing separate debuginfo for /usr/local/zend/ZendGuardLoader.so
                      (no debugging symbols found)…done.
                      Loaded symbols for /usr/local/zend/ZendGuardLoader.so
                      Reading symbols from /usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/opcache.so…done.
                      Loaded symbols for /usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/opcache.so
                      Reading symbols from /lib64/libnss_files.so.2…(no debugging symbols found)…done.
                      Loaded symbols for /lib64/libnss_files.so.2
                      Core was generated by `php-fpm: pool www ‘.
                      Program terminated with signal 11, Segmentation fault.
                      #0 0x0000000001868238 in ?? ()
                      Missing separate debuginfos, use: debuginfo-install bzip2-libs-1.0.5-7.el6_0.x86_64 cyrus-sasl-lib-2.1.23-13.el6_3.1.x86_64 glibc-2.12-1.149.el6_6.5.x86_64 keyutils-libs-1.4-5.el6.x86_64 krb5-libs-1.10.3-42.el6.x86_64 libcom_err-1.41.12-22.el6.x86_64 libcurl-7.19.7-46.el6.x86_64 libidn-1.18-2.el6.x86_64 libselinux-2.0.94-5.8.el6.x86_64 libssh2-1.4.2-1.el6.x86_64 libxml2-2.7.6-20.el6_7.1.x86_64 nspr-4.9.2-1.el6.x86_64 nss-3.14.0.0-12.el6.x86_64 nss-softokn-freebl-3.12.9-11.el6.x86_64 nss-util-3.14.0.0-2.el6.x86_64 openldap-2.4.23-31.el6.x86_64 openssl-1.0.1e-42.el6_7.2.x86_64 zlib-1.2.3-29.el6.x86_64
                      (gdb)

                      查了,php.ini,

                      [Zend ZendGuard Loader]
                      ;zend_extension=/usr/local/zend/ZendGuardLoader.so
                      zend_loader.enable=1
                      zend_loader.disable_licensing=0
                      zend_loader.obfuscation_level_support=3
                      zend_loader.license_path=

                      [opcache]
                      zend_extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/opcache.so
                      ;上面zend_extension路径为opcache.so的路径
                      opcache.force_restart_timeout=3600
                      opcache.memory_consumption=128
                      opcache.interned_strings_buffer=8
                      opcache.max_accelerated_files=4096
                      opcache.revalidate_freq=60
                      opcache.fast_shutdown=1
                      opcache.enable_cli=1
                      opcache.enable=1
                      ;opcache.blacklist_filename=/home/wwwroot/www.zaixianfeicui.com/blacklist

                      定义了2次 zend_extension
                      注释了
                      ;zend_extension=/usr/local/zend/ZendGuardLoader.so
                      即可了,

                      谢谢。