zoukankan      html  css  js  c++  java
  • Symbol Versioning for GCC:一种对动态库符号进行版本控制的技术

    关键词:--version-script、Symbol Versioning等等。

    gcc提供了Symbol Versioning,通过对Symbol进行版本化,可以达到symbol级别的兼容性检查。

    1. 概要介绍

    Symbol Versinoning只适用于动态库,首先对需要Versioning的Symbol通过--version-script指定,进行Versioning。

    然后引用者可以指定所需要的Symbol并指定Version。

    最后在运行时,动态库加载时会对Symbol和Version进行匹配,失败后会报错并停止加载运行。

    2. 相关参考文档

    3. 示例

    3.1 创建示例程序

    目录结构如下,主程序main.c,以及库文件liba和CMakeLists.txt。

    ├── CMakeLists.txt
    ├── liba
    │   ├── a.c
    │   ├── a.h
    │   └── a.lds
    └── main.c

    CMakeLists.txt:

    cmake_minimum_required(VERSION 3.0)
    
    project(versionsymbol C CXX)
    
    set(A_SRCS "")
    
    include_directories("${PROJECT_SOURCE_DIR}/liba/")
    
    file(GLOB_RECURSE  A_SRCS ${PROJECT_SOURCE_DIR}/liba/*.c)
    file(GLOB_RECURSE  A_LDS ${PROJECT_SOURCE_DIR}/liba/a.lds)
    message(${A_LDS})
    add_library(a SHARED ${A_SRCS})
    target_link_libraries(a "-Wl,--version-script=${A_LDS}")
    
    
    set(MAIN_SRCS "")
    file(GLOB_RECURSE  MAIN_SRCS ${PROJECT_SOURCE_DIR}/main.c)
    add_executable(main ${MAIN_SRCS})
    target_link_libraries(main a)

    liba:

    a.c:
    #include <stdio.h>
    
    int func_versioning()
    {
            return 1;
    }
    
    a.h:
    int func_versioning();
    
    a.lds:
    VER_1.0{
        func_versioning;
    };

    main:

    #include <stdio.h>
    #include <a.h>
    
    int main(void)
    {
      printf("func_versioning()=%d
    ", func_versioning());
    }

    3.2 测试1

    首先编译VER_1.0版本的func_with_version,查看main和lib.so的符号:

    File: liba.so
    
    Symbol table '.dynsym' contains 14 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
    ...
         8: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS VER_1.0
         9: 0000000000201028     0 NOTYPE  GLOBAL DEFAULT   23 _end
        10: 00000000000006c0    11 FUNC    GLOBAL DEFAULT   12 func_versioning@@VER_1.0
    ...
    
    Symbol table '.symtab' contains 56 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
    ...
        46: 00000000000006c0    11 FUNC    GLOBAL DEFAULT   12 func_versioning
    ...
    
    File: main
    
    Symbol table '.dynsym' contains 21 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
    ...
         3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND func_versioning@VER_1.0 (4)
    ...
         9: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS VER_1.0
    ...
    
    Symbol table '.symtab' contains 70 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
    ...
        56: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND func_versioning@@VER_1.0
    ...

    即可生成带版本号的符号。

    修改a.lds为:

    VER_2.0{
        func_versioning;
    };

    然后用VER_1.0的main和VER_2.0的liba.so:

    ./main_1.0: /home/al/versioned_symbol/liba.so: version `VER_1.0' not found (required by ./main_1.0)

    用VER_2.0的main和VER_1.0的liba.so:

    ./main_2.0: /home/al/versioned_symbol/liba.so: version `VER_2.0' not found (required by ./main_2.0)

    这是检查Versioning版本号没有报错。

    3.3 测试2

    增加一个函数:

    #include <stdio.h>
    
    int func_versioning()
    {
            return 1;
    }
    
    int func2_versioning()
    {
            return 1;
    }

    前后两次修改a.lds后如下:

    VER_1.0{
        func_versioning;
        func2_versioning;
    };
    
    VER_2.0{
    };

    再次:

    VER_1.0{
        func2_versioning;
    };
    
    VER_2.0{
        func_versioning;
    };

    执行结果如下:

    ./main_1.0: relocation error: ./main_1.0: symbol func_versioning, version VER_1.0 not defined in file liba.so with link time reference

    这是检查到了Versioning版本号,但是对应符号func_versioning的VER_1.0没有匹配上。

  • 相关阅读:
    一目了然卷积神经网络
    浅析 MVC Pattern
    程序员读书清单
    “数据中台”的再思考
    火锅、报表与数据库的故事
    从NoSQL到NewSQL,谈交易型分布式数据库建设要点
    从架构特点到功能缺陷,重新认识分析型分布式数据库
    YCSB测试HBase远程完全分布式集群
    NoSQL性能测试工具YCSB-Running a Workload
    再谈数据库事务隔离性
  • 原文地址:https://www.cnblogs.com/arnoldlu/p/13552504.html
Copyright © 2011-2022 走看看