zoukankan      html  css  js  c++  java
  • 利用dmesg和addr2line来对(动态库里的)段错误进行调试

    工作中,我们在varnish的基础上,利用vmod机制,实现了一个可以定制策略,且策略可自动加载而不需重新启动引擎的cache(平时,大家对varnish的利用,cache策略都定义在一个vcl配置文件中,每次对策略进行修改,都需要重新启动varnish,从而使得策略生效,且当部署在varnish后面的站点很多时,不方便对每站点的cache策略进行个性化的定制),这里各种策略的控制以及加载都实现在一个vmod模块里(libvmod_ngcache.so),很开心,产品上线了。那么问题来,(挖掘机技术那家强?)当程序上到线上的时候,有时会出现各种bug,尤其是当程序崩溃了,而又没有对相应的core dump信息进行保存的时候,怎么定位问题出在程序的哪个位置就成为了一个难题,这篇文章就以我们的cache为实例,来示例定位问题。

     

    解决方法:

    程序发生段错误时,提示信息很少,在没有保存相应的core dump信息的情况下,要对这类错误进行调试尤为显得捉襟见肘,幸运的是我们可以利用linux系统自带的一些小工具来查看段错误发生的各种信息:

     

    dmesg 可以在应用程序崩溃的时候,显示内核中保存的相关信息:

    root@****:/home/l7# dmesg-T | grep varnishd

    [Thu Dec  421:25:58 2014] varnishd[16470] general protection ip:7feb693443bbsp:7feb669ea1e0 error:0 in libvmod_ngcache.so.1.0.0[7feb69331000+52000]

     

    有时候,通过查看相应的内核日志,也可以查看到同样的信息:

    root@****:/home/l7# cat/var/log/kern.log

    Dec  5 07:49:34 ****kernel: [17376990.017811] varnishd[16470] general protection ip:7feb693443bbsp:7feb669ea1e0 error:0 in libvmod_ngcache.so.1.0.0[7feb69331000+52000]

     

    root@****:/home/l7# dmesg| grep varnishd

    [17376990.017811] varnishd[16470] general protectionip:7feb693443bb sp:7feb669ea1e0 error:0 inlibvmod_ngcache.so.1.0.0[7feb69331000+52000]

    输出信息内容:段错误发生的时间([17376990.017811])、发生段错误的程序名称[进程号](varnishd[16470])、引起段错误发生的指令指针地址(general protection ip:7feb693443bb)、引起段错误发生的堆栈指针地址(sp:7feb669ea1e0)、错误代码(error:0)、libvmod_ngcache.so.1.0.0[7feb69331000+52000](In the libfoo.so[NNNNNN+YYYY] part, the NNNNNN is where the librarywas loaded. Subtract this from theinstruction pointer (ip) and you'll getthe offset into the .so of the offendinginstruction. Then you can use objdump -DCgl libfoo.so andsearch for the instruction at that offset. You should easily be able to figureout which function it is from the asm labels.If the .so doesn't haveoptimizations you can also try using addr2line-e libfoo.so <offset>, 52000 = 0xcb20)。

     

    因此,有动作: 推荐方法二

    (一):

    ip:0x7feb693443bb -libvmod_ngcache.so.1.0.0[0x7feb69331000+YYYY] = 0x133bb

    root@****:/home/l7# objdump-DCgl /usr/local/lib/varnish/vmods/libvmod_ngcache.so | grep -C 10 133bb

       1339c: 0f b6 c2               movzbl%dl,%eax

       1339f: 48 8b 5c c1 08         mov    0x8(%rcx,%rax,8),%rbx

    /var/lib/jenkins/workspace/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/varnish_vmod/libvmod-ngcache/src/sfksearch.c:864

       133a4: 48 85 db               test   %rbx,%rbx

       133a7: 74 1f                  je     133c8<KTrieSearch+0x1b8>

       133a9: 44 8b 6c 24 2c         mov    0x2c(%rsp),%r13d

       133ae: 4c 89 fd               mov    %r15,%rbp

       133b1: 0f 1f 80 00 00 00 00   nopl   0x0(%rax)

    /var/lib/jenkins/workspace/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/varnish_vmod/libvmod-ngcache/src/sfksearch.c:868

       133b8: 0f b6 c2               movzbl%dl,%eax

       133bb: 39 03                  cmp    %eax,(%rbx)

       133bd: 74 71                  je     13430 <KTrieSearch+0x220>

    /var/lib/jenkins/workspace/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/varnish_vmod/libvmod-ngcache/src/sfksearch.c:895

       133bf: 48 8b 5b 08            mov    0x8(%rbx),%rbx

       133c3: 48 85 db               test   %rbx,%rbx

       133c6: 75 f0                  jne    133b8<KTrieSearch+0x1a8>

    KTrieSearchNoBC():

    /var/lib/jenkins/workspace/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/varnish_vmod/libvmod-ngcache/src/sfksearch.c:979

       133c8: 44 01 74 24 30         add    %r14d,0x30(%rsp)

    /var/lib/jenkins/workspace/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/varnish_vmod/libvmod-ngcache/src/sfksearch.c:977

       133cd: 49 83 c7 01            add    $0x1,%r15

    这里基本上可以定位到出问题的函数了。

     

    (二):

    ip:0x7feb693443bb -libvmod_ngcache.so.1.0.0[0x7feb69331000+YYYY] = 0x133bb

    root@****:/home/l7# addr2line-e /usr/local/lib/varnish/vmods/libvmod_ngcache.so 0x133bb -f

    KTriePrefixMatch

    /var/lib/jenkins/workspace/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/l7cache_ngcache_vmod_for_varnish3.0.5_First_Edition/varnish_vmod/libvmod-ngcache/src/sfksearch.c:868

     

    (三):

    ip:0x7feb693443bb -libvmod_ngcache.so.1.0.0[0x7feb69331000+YYYY] = 0x133bb

    root@****:/home/l7# gdb/usr/local/lib/varnish/vmods/libvmod_ngcache.so

    ......

    (gdb) disass0x133bb

      ......

      0x0000000000013399 <+393>:    xor    %r14d,%r14d

      0x000000000001339c <+396>:    movzbl%dl,%eax

      0x000000000001339f <+399>:    mov    0x8(%rcx,%rax,8),%rbx

      0x00000000000133a4 <+404>:    test   %rbx,%rbx

      0x00000000000133a7 <+407>:    je     0x133c8 <KTrieSearch+440>

      0x00000000000133a9 <+409>:    mov    0x2c(%rsp),%r13d

      0x00000000000133ae <+414>:    mov    %r15,%rbp

      0x00000000000133b1 <+417>:    nopl   0x0(%rax)

      0x00000000000133b8 <+424>:    movzbl%dl,%eax

       0x00000000000133bb <+427>:   cmp   %eax,(%rbx)

      0x00000000000133bd <+429>:    je     0x13430 <KTrieSearch+544>

      0x00000000000133bf <+431>:    mov    0x8(%rbx),%rbx

      0x00000000000133c3 <+435>:    test   %rbx,%rbx

      0x00000000000133c6 <+438>:    jne    0x133b8 <KTrieSearch+424>

     

    另:推荐一些工具,供大家学习使用:

    gdb、ldd、eu-readelf、readelf、objdump、dmesg、addr2line、nm、catchsegv;

    另外建议,像这种线上的程序,尽量配置当程序crash的时候有coredump文件产生或者记录stack backtrace。

     

    问题的查找,参考了网络上很多的文章和Q&A,在这里表示感谢并列出原文引用,谢谢!

    Refer:

    1、"Linux环境下段错误的产生原因及调试方法小结"

    http://www.cnblogs.com/panfeng412/archive/2011/11/06/segmentation-fault-in-linux.html

     

    2、"How doyou read a segfault kernel log message"

    http://stackoverflow.com/questions/2179403/how-do-you-read-a-segfault-kernel-log-message

     

    3、"DebuggingC++ (Part 3): dmesg"

    http://enki-tech.blogspot.com/2012/08/debugging-c-part-3-dmesg.html

     

    4、"Introductionto segmentation fault handling"

    http://www.slideshare.net/noobyahoo/introduction-to-segmentation-fault-handling-5563036

     

    5、"Pythoncrashed; how to decode segfault in dmesg log?"

    http://stackoverflow.com/questions/21269999/python-crashed-how-to-decode-segfault-in-dmesg-log

  • 相关阅读:
    内存管理 Autorelease、retain、copy、assign的set方法和含义?
    解决 项目cocoapods diff: /../Podfile.lock: No such file or directory
    iOS按钮点击的频率 防止按钮连续点击时重复执行按钮的点击方法
    iOS 网络篇--PDF网络文件下载和打开
    使用runtime获取属性
    取到 tableview 自定义section header 上的button
    JavaScript第一天 改变DIV的样式
    iOS 因为reason: 'Pushing the same view controller instance more than once is not supported而奔溃(下)
    iOS 因为reason: 'Pushing the same view controller instance more than once is not supported而奔溃(上)
    iOS缓存功能
  • 原文地址:https://www.cnblogs.com/wangshaowei/p/14063595.html
Copyright © 2011-2022 走看看