You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用dl_iterate_phdr获取共享对象大小的相关技术疑问

dl_iterate_phdr相关问题解答

1. 如何在使用dl_iterate_phdr时获取共享对象的大小?

通过遍历struct dl_phdr_info中的程序头数组(dlpi_phdr),筛选出类型为PT_LOAD的段,计算每个LOAD段的结束地址(基址dlpi_addr + 段偏移p_vaddr + 段内存大小p_memsz),最终取所有PT_LOAD段结束地址的最大值,减去共享对象的加载基址dlpi_addr,得到的就是整个共享对象的内存占用大小。

2. 为什么struct dl_phdr_info结构体中没有size成员?

原因主要有两点:

  • 共享对象的“大小”没有统一定义:不同场景下需要的大小统计范围不同——有的仅需统计可加载段的总大小,有的可能要包含非加载段,动态链接器无法预设一个满足所有需求的“标准大小”。
  • 设计理念导向:dl_iterate_phdr的核心是暴露程序头原始信息,把具体计算逻辑交给调用者,既保持了结构体的简洁性,又能让用户根据自身需求灵活处理,避免冗余。

3. 是否必须解析/proc/self/maps来实现该需求?

不需要。通过dl_iterate_phdr遍历程序头的方式就能直接计算出大小,而且这种方法不依赖/proc文件系统(部分嵌入式Linux环境可能没有/proc),比解析/proc/self/maps更直接高效。解析/proc/self/maps是另一种可行方案,但绝非必须。

修改后的示例代码

#define _GNU_SOURCE

#include <link.h>
#include <stdio.h>
#include <stdint.h>

int iterate(struct dl_phdr_info *info, size_t size, void *data)
{
    if (info->dlpi_name[0] == '\0') {
        // 可选择跳过主程序,不需要则删除此判断
        return 0;
    }

    uintptr_t max_end = 0;
    for (int i = 0; i < info->dlpi_phnum; ++i) {
        const ElfW(Phdr) *phdr = &info->dlpi_phdr[i];
        if (phdr->p_type == PT_LOAD) {
            uintptr_t seg_end = info->dlpi_addr + phdr->p_vaddr + phdr->p_memsz;
            if (seg_end > max_end) {
                max_end = seg_end;
            }
        }
    }

    size_t so_size = max_end - info->dlpi_addr;
    printf("lib '%s' was loaded at %lx and the size is %zu bytes\n", 
           info->dlpi_name, (unsigned long)info->dlpi_addr, so_size);
    return 0;
}

int main()
{
    dl_iterate_phdr(&iterate, NULL);
    return 0;
}

内容的提问来源于stack exchange,提问作者zomega

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:25:19