Nov30

【转载】Linux下动态链接库so文件覆盖导致coredump问题的分析

Author: ifreax  Click: 12107   Date: 2011.11.30 @ 11:10:59 am Category: Linux C/C++编程

尝试解答以下问题:

      1.为什么cp的方式更新运行中进程的so,程序会coredump

      2.采用什么方式更新已经加载了的so,就可以避免coredump

 

我们的公共组件绝大部分都支持so形式的自定义插件,比如s++,qzhttp,ttc。在不停进程更新so的时候往往会产生coredump,并且肯定core得莫名其妙,core得让人心碎。

 

先看一下用cp的方式更新so的时候发生了什么事情

strace cp new.so old.so #strace是人间利器


发现老的sotrunc了,这个过程发生的具体的事情是:

      1.应用程序通过dlopen打开so的时候,kernel通过mmapso加载到进程地址空间,对应于vma里的几个page.

      2.在这个过程中loader会把so里面引用的外部符号例如malloc printf等解析成真正的虚存地址。

      3.socp覆盖时,确切地说是被trunc时,kernel会把so文件在虚拟内的页purge 掉。

      4.当运行到so里面的代码时,因为物理内存中不再有实际的数据(仅存在于虚存空间内),会产生一次缺页中断。

      5.Kernelso文件中copy一份到内存中去,a)但是这时的全局符号表并没有经过解析,当调用到时就产生segment fault ,  b)如果需要的文件偏移大于新的so的地址范围,就会产生bus error.

 

所以,如果用相同的so去覆盖

      A) 如果so 里面依赖了外部符号,coredump

      B) 如果so里面没有依赖外部符号,运气不错,不会coredump

 

所有问题的产生都是因为sotrunc了一把,所以如果不用turnc的方式就避免这个问题。Ok,该我们的install 上场了。

strace install new.so old.so



install 的方式跟cp不同,先unlinkcreat,当unlink的时候,已经map的虚拟空间vma中的inode结点没有变,只有inode结点的引用计数为0是,kernel才把它干掉。

也就是新的so和旧的so用的不是同一个inode结点,所以不会相互影响。这时只有得启程序才会使用到新的so。所以采用这种方式的话就可以避免先stop进程,更新so,再重启进程这样比较耗时的操作。


TAG:   coredump so cp linux

    评论
    • 提交

    分类

    标签

    归档

    最新评论

    Abyss在00:04:28评论了
    Linux中ramdisk,tmpfs,ramfs的介绍与性能测试
    shallwe99在10:21:17评论了
    【原创】如何在微信小程序开发中正确的使用vant ui组件
    默一在09:04:53评论了
    Berkeley DB 由浅入深【转自架构师杨建】
    Memory在14:09:22评论了
    【原创】最佳PHP框架选择(phalcon,yaf,laravel,thinkphp,yii)
    leo在17:57:04评论了
    shell中使用while循环ssh的注意事项

    我看过的书

    链接

    其他

    访问本站种子 本站平均热度:8823 c° 本站链接数:1 个 本站标签数:464 个 本站被评论次数:94 次