利用所提供的工具ranlib,观察对动态加载 libtest 库之前、之后,以及释放动态库之后的内存使用情况
时间: 2023-12-03 20:43:08 浏览: 134
首先,我们需要编写一个简单的测试程序,用于加载 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 技术的操作系统可能会在每次运行时随机分配虚拟地址,导致不同的运行实例映射到的物理地址不同。因此,建议在测试环境中多次运行测试程序,以获取更准确的结果。
阅读全文