作者: yylogo

  • Linux库静态替换解析:为什么覆盖动态链接库so会导致进程闪退

    总结

    遇到一个这样的问题,我最近把公司git ci自动化的流程向更先进的开源社区的方式推进了一点,我们修改了服务端so库,将新编译的so用cp指令覆盖掉旧的so会直接导致所有进程闪退。

    但是我们发现先rm旧的文件,再复制新的文件不会导致闪退,这个就非常纳闷了,处于不理解和好奇就深入研究了一下,最终总结是这样:

    这个闪退应该是分了几个流程:

    1. 加载so的时候是把整个so用文件映射到内存里,然后利用文件系统的lazy_load读内存
    2. cp的时候会复用旧的inode,操作系统对这个文件的索引会被改变
    3. 程序读取到原来没有的函数就会触发系统的load,然后去对应的偏移量读对应的block
    4. 闪退

    rm不闪退是因为:

    1. 旧的so因为还被引用(记录在INode上),所以不会立马删除对应的block
    2. 新的so会使用新的inode
    3. 程序中断读取文件的时候,会读取到旧文件的数据

    内核中mmap对应的结构:
    file

    可以看到其中有一个struct file表明一个打开的文件套接口,进一步看这个接口是这样:
    file
    整体的脉络相对就理清楚了。

    扩展:链接库

    众所周知,一般库文件会分为两种,静态库和动态库。

    静态库是在编译时将库的代码打包成。a文件,最终链接到可执行文件中。

    动态库在编译时需要开启-fPIC开启内存无关的编译方式编译成so文件,在程序运行时动态加载。

    静态链接库,它会伴随可执行文件运行被加载,它已经被ld链接器把库和执行文件放在一起了,我们将ELF文件映射到相应的运行地址,然后将PC寄存器指向entry即可。

    动态链接库的加载过程就比较复杂,可以看参考[7]文章的内容,讲的非常细致,简单地说动态链接库是真的动态,100个进程共用一个动态链接库,这个库在内存中实际占用的大小也只有一份。
    它在内核中的实现是按照制度的方式映射同一个文件中的部分(如动态代码段),这个过程中会创造引用计数。

    非常详细的解释可以读参考[7]!!!

    参考文章

    [1], https://cloud.tencent.com/developer/article/1040842
    [2], https://www.linuxidc.com/Linux/2011-01/31622.htm
    [3], https://www.cs.toronto.edu/~simon/html/understand/node33.html
    [4], https://elixir.bootlin.com/linux/latest/source/include/linux/fs.h
    [5], https://zhuanlan.zhihu.com/p/401446080
    [6], https://zhuanlan.zhihu.com/p/287863861
    [7], https://blog.ideawand.com/2020/02/15/how-does-linux-shared-library-versioning-works/
    [8], https://blog.csdn.net/weixin_44966641/article/details/120631079

    End.

  • 反思一下中途开香槟

    很久没好好开发了,之前一直推脱是卡在数值,但是功能上还有很多缺失,内心有点抵触这个各种事情的继续推进。

    行百里者半九十,深刻体会到这句话,前面志得意满太多了,炫耀获得的满足感太多了。

    心里就有一种很错位的自豪,这一件很伟大的事情我已经做完一半了,但是遇到真正的困难和复杂我就开始踌躇不前,我会找很多听起来合理的推脱借口,听起来一定是合理的,我这方面的嘴上功夫真的是一流的,我太清楚自己了。所以要彻彻底底从未来的结果倒推,东西能做出来那就OK,东西做不出来那就是又一次遇到demo向完整的作品转型会遇到的困难,然后自我垮掉了。

    无论是游戏开发还是B站账号,都是有一点小成绩小成果,然后就停滞了,我好像一直是这样,不止是这两件事情,在我身上的好多事情都是这样,前期快速推进,中期就停滞不前,最后能落地的屈指可数。

    虽然每件事儿的卡点都各不相同,当事情不止一次发生就只能倒推出是我自身阻塞住了,甚至有时候我还会想,我是不是就适合做这种先驱型的工作,但回过头就觉得这是一种傲慢,巨大的傲慢。

    一个完整的优秀的事情,它是不是虎头真的不重要,最重要的只有两件事:
    1、完成这件事情;
    2、结局是完整的,达到目标的;

    半路开香槟这个事情是我的问题,需要深度反思一下,我现在是获得了一点点的关注和影响力,但是远远不够,必须要全部做完!!!

    回到亡灵集结号,现在的框架要支持更复杂的技能好像很麻烦,我想要做多功能合一的按钮好像很复杂,我想要去可以在修建状态和战斗状态分别操纵小兵好像很麻烦,现在AI无论多远都会自动寻敌这个事情不好,但是想改好似乎对AI框架的修改相当多……

    诸如此类,我大概是在潜意识的有一些感知到这些困难,并且开始逃避,享受前半段的错位就好,后半段的艰辛我不想干了。一次又一次一次又一次,哎。

    我真的还挺讨厌自己的,太熟悉以至于太了解缺陷,又太想自己好以至于经常苦恼。好在是从一次又一次的挣扎中,学会跟自己对话。找一个大片的时间,坐下来不去思考,就是打字,意识流的敲键盘,然后混乱无头绪的思绪就会先像岛屿漂浮起来,欲望、挣扎和方向会像可视化的方式浮现在眼前。

    要做的就只有一件事情,连线,也许内在的心理运行机理不是连线这样,但是对错这件事情不是最重要的,最重要的是有一个合理的解释,并且继续向方向前进。弗洛伊德的是对的吗?阿德勒是对的吗?该从孩童时期的伤害中去寻找自我还是从否定自我的存在主义中寻找自我,真相很重要吗?不重要,这些只是让我们健康的工具。感冒能好就行,谁在乎是体质原因还是哪种药更有用。

    1w粉有点难了,保证每个月2个视频吧,大概是这个产出数量,然后游戏要在6月底开发完,git提交要忙碌起来了。

    中途可以开香槟,但是结局的香槟最重要,完成就是胜利!!

    End。

  • 修复了虚幻旋转的bug

    昨天通宵定位修复了之前demo移动有问题的bug,还挺开心的,一个可能是因为误差导致的悬空,另外一个是官方的bug,也是我改了bug的同事还给官方提供了一个request,希望能过。

  • 了解一下boost的fiber

    fiber是纤程,用户级纤程,在用户层提供调度管理器,可以在系统线程上切换纤程,它主要的好处:

    • 切换非常快,按照boost的数据,快100倍[1];
    • 纤程访问父线程的数据不需要加锁,因为不具备竞争;
    • 基于完全同步的写法来实现的fiber阻塞和切换;

    引用

    1. https://www.boost.org/doc/libs/1_83_0/libs/fiber/doc/html/fiber/performance.html
    2. https://blog.csdn.net/hezhanran/article/details/110792367
    3. https://agraphicsguynotes.com/posts/fiber_in_cpp_understanding_the_basics/
  • 很想买小米14

    这两天一直在被新手机诱惑,很想买小米14.
    不得不说,铺天盖地的宣传,好看的机身都很不错,性能提升也很夸张。挺吸引人的。
    我仔细想了一下,我买手机好像从来不是因为这些宣传,而是因为上一台坏了。

    有必要吗,其实日常性能完全够用的。

    挺纠结的,再等等吧

  • 关于制定计划

    脱离于时间去谈计划是很难执行的,例如我如果制定一个计划,周末读一本书,这就是一件可以让自己快乐的口号,但它不具备成为计划的价值。

    我周末要学blender,要看python源码都是如此的口号,口号和计划是非常相似的。

    一个可执行的计划是过程主义和结果主义的巧妙平衡,既能就事论事地量化目标,同时还会考虑到执行所需要的时间以及代价。

    例如我周末要看一本书,是一个不好的计划,它没考虑书的长度,这个计划跟我的关系很小,它是口号。

    我周末要打开三次这本书,每次至少读一页,这是一个增强执行力的计划。

    我周末要看8个小时书,每天4个小时,这是一个相比看一整本书更可行的计划。

  • 夸夸金铲铲之战

    周末玩了一下金铲铲,二十把上到铂金,一把半个小时,10多个小时就被吃没了。

    惊叹于装备的设计,卡能不能Carry取决于装备和英雄的结合。

    更惊叹于随机的懂人心,抓住每个流派期待随机系统的调整,直接给到玩家。

    尤其惊讶于商业模式的简单,真的是有钱的捧个钱场,没钱的捧个人场的模式,什么都不买能体验到所有的游戏内容,没有一点内容阻碍。

    当今几乎所有的免费游戏,比如王者、第五人格、永劫无间,这些想体验到全部的游戏内容是需要付费的,因为英雄是需要买的。

  • 人做不了超越自己认知的东西

    人做不了超越自己认知的东西。

    如果相信苹果眼镜上市之后会引领潮流,那么安卓阵营也不会停滞,那如果这个时候我下场不做ToC,而是做ToB,我去思考AR/VR设备里所需要的硬件,例如玻璃,例如按钮。

    但是这个是很难的,我没有工厂资源,我也没有上游厂商的供应链资源,我空有一腔想挣钱的热情。

  • 注重过程的结果主义者

    我一直以为我是一个过程主义者,但是最近我才瞄到我是个结果主义者,甚至抵达结果有些许的不择手段,只是手里的武器不多,否则我应该是一个很恶劣的人。

    我只是会在达到最终结果的路上,设立很多小的目标。

    注重过程的结果主义者。