zoukankan      html  css  js  c++  java
  • 关于so文件cp覆盖导致调用者core的研究

    先说cp好mv/rm的区别:

    cp from to,则被覆盖文件 to的inode依旧不变(属性也不变),内容变为from的;

    mv from to,则to的inode变为from的,相应的,to的属性也成了from的;rm类似;

    问题,假如程序 main.out依赖的so文件libtest.so被cp掉,会发生什么?

    strace cp test2 test  2>&1 | grep open.*test
    open("test2", O_RDONLY|O_LARGEFILE)     = 3
    open("test", O_WRONLY|O_TRUNC|O_LARGEFILE) = 4

      cp的实现逻辑不是“rm + open(O_CREAT)”,而上面的实现方式才是最可靠的(保证了时序安全和目标文件的属性)。这解释了为什么cp的目标文件会继承被覆盖文件的属性而非源文件。

    Linux由于Demand Paging机制的关系,必须确保正在运行中的程序镜像(注意,并非文件本身)不被意外修改,因此内核在启动程序后会绑定 内存页 到这个so的inode,而一旦此inode文件被open函数O_TRUNC掉,则kernel会把so文件对应在虚存的页清空,这样当运行到so里面的代码时,因为物理内存中不再有实际的数据(仅存在于虚存空间内),会产生一次缺页中断。Kernel从so文件中copy一份到内存中去,a)但是这时的全局符号表并没有经过解析,当调用到时就产生segment fault , b)如果需要的文件偏移大于新的so的地址范围,就会产生bus error。

    备注:如果用相同的so去cp覆盖
    A) 如果so 里面依赖了外部符号(如标准库),coredump
    B) 如果so里面没有依赖外部符号,运气不错,不会coredump

    不必说,先rm再cp的话,新文件的inode其实已经改变了,原inode并没有被真正删除,直到内核释放对它的引用(引用旧SO的进程退出,而新进程当然呈现的就是新so的效果了,新进程和core无关啦)。同理,mv只是改变了文件名,其inode不变,新文件使用了新的inode。

    参考: 

    [1]http://www.piao2010.com/%E4%B8%BA%E4%BD%95cp%E8%A6%86%E7%9B%96%E8%BF%9B%E7%A8%8B%E7%9A%84%E5%8A%A8%E6%80%81%E5%BA%93so%E4%BC%9A%E5%AF%BC%E8%87%B4coredump

    [2]http://blog.csdn.net/wei_yongtao/article/details/40145891

  • 相关阅读:
    未解
    HDU 4642 Fliping game 解题报告
    HDU 4639 Hehe 解题报告
    深入浅出Node.js (11)
    JS文本框获取焦点
    深入理解 BFC
    JS 中函数名后面加与不加括号的区别
    ES6 箭头函数
    sublime 格式化代码
    <!--more-->搭建的博客设置主页内容高度
  • 原文地址:https://www.cnblogs.com/zhaoyl/p/4964811.html
Copyright © 2011-2022 走看看