我需要获取以下进程段的开始和结束地址:代码、数据、堆栈、环境。我知道它是如何位于内存中的,但不知道如何使用 api 调用或其他方式获取它。我已经找到了如何使用这段代码开始一些片段
#include <stdio.h>
int temp_data = 100;
static int temp_bss;
void print_addr ( void )
{
int local_var = 100;
int *code_segment_address = ( int* ) &print_addr;
int *data_segment_address = &temp_data;
int *bss_address = &temp_bss;
int *stack_segment_address = &local_var;
printf ( "\nAddress of various segments:" );
printf ( "\n\tCode Segment : %p" , code_segment_address );
printf ( "\n\tData Segment : %p" , data_segment_address );
printf ( "\n\tBSS : %p" , bss_address );
printf ( "\n\tStack Segment : %p\n" , stack_segment_address );
}
int main ( )
{
print_addr ();
return 0;
}
但我不知道如何找到每个段的结尾。我唯一的想法是,一段的结尾是另一段的开始。 请说明如何使用 C 和 linux API 执行此操作。
最佳答案
我不确定数据或堆段是否定义明确且唯一(特别是在多线程应用程序中,或者只是在使用动态库(包括 libc.so
)的应用程序中)。换句话说,不再有任何明确定义的文本、数据或堆段的开始和结束,因为今天一个进程有很多这样的段。所以你的问题在一般情况下甚至没有意义。
大多数malloc
实现使用mmap(2)和 munmap
比 sbrk
您应该阅读更多关于 proc(5) 的内容.特别是,您的应用程序可以读取 /proc/self/maps
(或 /proc/1234/maps
用于 pid 1234 的进程)或 /proc/self/ map
;试试 cat/proc/self/maps
并考虑使用 fopen(3)在 "/proc/self/maps"
上(然后在 fgets
或 readline
上循环,最后快速地 fclose
).也许dladdr(3)可能是相关的。
您还可以阅读 ELF你的程序的标题,例如/proc/self/exe
。另见 readelf(1)和 objdump(1) & execve(2) & elf(5) & ld.so(8) & libelf .另请阅读 Levine's Linkers & Loaders书和Drepper's paper: How To Write Shared Libraries .
另见 this answer一个相关的问题(还有 that question )。请注意,最近的 Linux 系统有 ASLR ,所以在相同环境下运行相同程序的两个相似进程的地址布局是不同的。
也尝试 strace(1)一些简单的命令或您的程序。你会更多地了解相关的syscalls(2) .另请阅读 Advanced Linux Programming
关于c - 获取流程段的开始和结束 C/C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26444914/