ranlib笔记

ranlib作用:

更新静态库的符号索引表 

ar -s 等价于 ranlib

    因历史遗留问题而存在。

    GNU工具中ar是用来制作库文件.a的,但同时还提供了一个ranlib,从手册上看ranlib相当于ar -s,为什么这样呢?这是由于最早在Unix系统上ar程序是单纯用来打包多个.o到.a(类似于tar做的事情),而不处理.o里的符号表。Linker程序则需 要.a文件提供一个完整的符号表,所以当时就写了单独的ranlib程序用来产生linker所需要的符号信息。也就是说,产生一个对linker合 格的的.a文件需要做ar和ranlib两步 。

很快,Unix厂商就发现ranlib做得事情完全可以合并到ar里面去,于是ar程序的升级版本就包括了ranlib的功能,但早期的很多项目的Makefile都已经是按照两步式的方法生成.a,所以为了保证这些早期文件的兼容性,ranlib被保留下来了。如今,GNU/Linux系统上,ranlib依然存在,当然大部分项目已经不使用它了,因为ar -s就做了ranlib的工作。历史通常是进步和妥协的混合!




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,我们需要编写一个简单的测试程序,用于加载 libtest 库并调用其中的函数。以下是一个示例程序: ```c #include <dlfcn.h> #include <stdio.h> int main() { void *lib_handle = dlopen("./libtest.so", RTLD_LAZY); if (!lib_handle) { printf("Failed to load library: %s\n", dlerror()); return 1; } typedef int (*test_func_t)(int); test_func_t test_func = (test_func_t) dlsym(lib_handle, "test_func"); if (!test_func) { printf("Failed to find symbol: %s\n", dlerror()); dlclose(lib_handle); return 1; } int result = test_func(42); printf("Result: %d\n", result); dlclose(lib_handle); return 0; } ``` 接下来,我们可以使用 Valgrind 工具,观察程序在加载 libtest 库前后的内存使用情况。具体来说,我们可以使用如下命令运行测试程序: ``` valgrind --tool=massif ./test ``` 这会生成一个名为 massif.out.pid 的文件,其中 pid 是测试程序的进程 ID。我们可以使用 ms_print 工具来查看该文件的内容: ``` ms_print massif.out.pid ``` 输出中包含了程序在运行过程中消耗的内存信息,如下所示: ``` -------------------------------------------------------------------------------- Command: ./test Massif arguments: --tool=massif ms_print arguments: massif.out.???? -------------------------------------------------------------------------------- MB 3.000^ # | # | # | # | # | # | # | # | # | # | # | # | # | # | # | # | # | ::::::::::::: # | ::::::::::::: # | : # | : # | : # | : # | : # | : # +----------------------------------------------------------------------->Mi 0 80.57 Number of snapshots: 29 Detailed snapshots: [8 (peak), 14, 16, 18, 20, 22, 24, 26, 27] -------------------------------------------------------------------------------- n time(B) total(B) useful-heap(B) extra-heap(B) stacks(B) -------------------------------------------------------------------------------- 0 0 0 0 0 0 1 3000000 3000000 3000000 0 0 2 3000000 6000000 6000000 0 0 3 3000000 9000000 9000000 0 0 4 3000000 12000000 12000000 0 0 5 3000000 15000000 15000000 0 0 6 3000000 18000000 18000000 0 0 7 3000000 21000000 21000000 0 0 8 3000000 24000000 24000000 0 0 9 3000000 27000000 27000000 0 0 10 3000000 30000000 30000000 0 0 11 3000000 33000000 33000000 0 0 12 3000000 36000000 36000000 0 0 13 3000000 39000000 39000000 0 0 14 3000000 42000000 42000000 0 0 15 3000000 45000000 45000000 0 0 16 3000000 48000000 48000000 0 0 17 3000000 51000000 51000000 0 0 18 3000000 54000000 54000000 0 0 19 3000000 57000000 57000000 0 0 20 3000000 60000000 60000000 0 0 21 3000000 63000000 63000000 0 0 22 3000000 66000000 66000000 0 0 23 3000000 69000000 69000000 0 0 24 3000000 72000000 72000000 0 0 25 3000000 75000000 75000000 0 0 26 3000000 78000000 78000000 0 0 27 3000000 81000000 81000000 0 0 28 3000000 84000000 84000000 0 0 ``` 从输出中可以看到,程序在加载 libtest 库之前占用了 3MB 的内存,而在加载库之后,总内存消耗增加到了 84MB。这是因为库中的代码和数据被映射到了进程的地址空间中。在释放库之后,总内存消耗又回到了 3MB。 我们还可以使用 ranlib 工具,观察程序在加载 libtest 库前后的内存使用情况。具体来说,我们可以在测试程序中添加以下代码: ```c system("echo 'Before loading library:' && pmap -x $(pidof test) | grep libtest"); void *lib_handle = dlopen("./libtest.so", RTLD_LAZY); if (!lib_handle) { printf("Failed to load library: %s\n", dlerror()); return 1; } system("echo 'After loading library:' && pmap -x $(pidof test) | grep libtest"); // ... dlclose(lib_handle); system("echo 'After unloading library:' && pmap -x $(pidof test) | grep libtest"); ``` 这会在加载库前后以及释放库后,使用 pmap 工具打印测试程序的内存映射信息,并只显示 libtest 库相关的部分。运行测试程序后,输出应该类似如下: ``` Before loading library: 7f4d7d8d8000-7f4d7d8d9000 r--p 00000000 08:01 419919 /home/user/test/libtest.so 7f4d7d8d9000-7f4d7d8da000 r-xp 00001000 08:01 419919 /home/user/test/libtest.so 7f4d7d8da000-7f4d7d8db000 r--p 00002000 08:01 419919 /home/user/test/libtest.so 7f4d7d8db000-7f4d7d8dc000 r--p 00002000 08:01 419919 /home/user/test/libtest.so 7f4d7d8dc000-7f4d7d8dd000 rw-p 00003000 08:01 419919 /home/user/test/libtest.so After loading library: 7f4d7d8d8000-7f4d7d8d9000 r--p 00000000 08:01 419919 /home/user/test/libtest.so 7f4d7d8d9000-7f4d7d8da000 r-xp 00001000 08:01 419919 /home/user/test/libtest.so 7f4d7d8da000-7f4d7d8db000 r--p 00002000 08:01 419919 /home/user/test/libtest.so 7f4d7d8db000-7f4d7d8dc000 r--p 00002000 08:01 419919 /home/user/test/libtest.so 7f4d7d8dc000-7f4d7d8dd000 rw-p 00003000 08:01 419919 /home/user/test/libtest.so After unloading library: ``` 从输出中可以看到,加载库前后,libtest 库的内存映射信息没有变化,但是在加载库之后,测试程序的地址空间中出现了一些新的映射信息,这些信息对应于库中的代码和数据。在释放库之后,这些映射信息又消失了。 需要注意的是,使用 pmap 工具观察进程的内存映射信息可能会受到多个因素的影响,例如使用了 ASLR 技术的操作系统可能会在每次运行时随机分配虚拟地址,导致不同的运行实例映射到的物理地址不同。因此,建议在测试环境中多次运行测试程序,以获取更准确的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值