改变一个正在被调用的 C++动态库,对需要调用它,且当前正在执行的的程序有什么影响? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
giskard

改变一个正在被调用的 C++动态库,对需要调用它,且当前正在执行的的程序有什么影响?

  •  
  •   giskard Dec 12, 2015 4279 views
    This topic created in 3791 days ago, the information mentioned may be changed or developed.

    我在 linux 下, C++ 源码编译成了一个动态库,然后有一个正在执行的程序需要调用这个库,这个程序要运行很长时间。这时,我忽然想起来库里有一个函数错了,我修改了这个函数,并且重新编译了一下这个动态库。改完以后,发现我的程序并没有停止运行,也没有任何反馈信息。可又有一次,同样的情形,当我修改了库,重新编译了库以后,程序却报错了,跟内存有关的报错,详细信息当时没保存下来,那么问题来了:

    1. 请问什么情况下改变了库会导致调用它的程序报错退出?什么情况不会?

    2. 在程序没有报错退出的情况下,程序是在调用我修改以后的库函数吗?

    本人不是 CS 专业,也不太懂编译原理相关理论,半路出家,现在搞一点科学计算,希望有经验的大大给一点指导,谢谢

    14 replies    2015-12-14 16:48:08 +08:00
    wsy2220
        1
    wsy2220  
       Dec 12, 2015   1
    如果你主程序是直接用 linker 链接到动态库的话,程序启动的同时就会链接到动态库,这时候修改库文件不会生效。
    如果是在代码里用 dlopen 函数运行时链接的话,在调用 dlopen 之前修改或者 dlclose 之后修改,主程序看到的就是新的动态库。

    看样子你应该没有用 dlopen 和 dlclose ,所以报错应该是旧版的库里有 bug 导致的。
    /td>
    wsy2220
        2
    wsy2220  
       Dec 12, 2015
    可以参考 CSAPP 第 7 章。
    giskard
        3
    giskard  
    OP
       Dec 12, 2015
    @wsy2220 感谢。请问我怎么才知道我是用 linker 还是 dlopen 呢?动态库是用 make 编译的,可执行程序是在 make 里用 -l 参数链接的,编译器是 g++。另,感谢推荐的书,我去看看第 7 章。
    wsy2220
        4
    wsy2220  
       Dec 12, 2015
    @giskard 那就是直接用 linker(ld)链接了
    skydiver
        5
    skydiver  
       Dec 12, 2015
    可以学习一下,都有哪些修改会改变 ABI ,哪些修改不会改变 ABI 。这方面的文章很多的。
    skydiver
        6
    skydiver  
       Dec 12, 2015
    @wsy2220 你没说到点子上。 lz 的程序本身就是动态链接的,报错是因为改变了动态链接库的 ABI 导致。
    wsy2220
        7
    wsy2220  
       Dec 12, 2015
    @skydiver 动态链接也分情况啊,以楼主这种方式动态链接,主程序还在运行的时候修改是不生效的...
    skydiver
        8
    skydiver  
       Dec 12, 2015 via Android
    @wsy2220 确实,如果已经在运行了,覆盖 so 应该没影响……这个确实奇怪
    billlee
        9
    billlee  
       Dec 12, 2015
    想到一个问题,替换动态库时,用 unlink 再 open 和直接 open O_TRUNC 是不是效果不一样啊?
    楼主你是用什么命令替换的?
    forcecharlie
        10
    forcecharlie  
       Dec 12, 2015
    你修改的是 磁盘镜像,无论是 编译时 link 或者 dlopen, 运行的时候都会先将 so 文件加载到内存中,只要不是重新从磁盘中读取,那么就依然使用的是 旧的 so, 而 Windows 不一样, Windows 的 dll 会被锁定,然后,替换不了。
    这也是为什么 linux rm -rf / 系统还能跑,重启起不来了。
    xufang
        11
    xufang  
       Dec 12, 2015 via Android
    楼上不懂装懂小学们去看淘宝团队技术博客,讲的很清楚可了。

    一句话结论,看运气,可能崩溃。
    xufang
        12
    xufang  
       Dec 12, 2015 via Android
    什么叫以己昏昏,使人昭昭 。这贴就是。不过我猜即使我在此指出了关键点,估计也不会有人顺藤摸瓜去学习一个。
    xufang
        13
    xufang  
       Dec 12, 2015   1
    给小学生一点提示,崩溃和 linux 对共享库的延迟加载有关,所以知道为啥说看运气了不。
    giskard
        14
    giskard  
    OP
       Dec 14, 2015
    @xufang 我是幼稚园还没毕业的。。。请问大神,您提到的淘宝团队技术博客,可否给一个链接看看?我 Google 过了,不确定我找到的是不是大神说的那个
    About     Help     Advertise     Blog     API     FAQ     Solana     5654 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 39ms UTC 06:59 PVG 14:59 LAX 23:59 JFK 02:59
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86