【问题标题】:Where are environment variables of a process is stored in linux?linux中进程的环境变量存储在哪里?
【发布时间】:2020-09-22 06:29:42
【问题描述】:

我做了一个简单的 C 程序,比如:

int main(int ac, char **av)
{
        char *str;
        int i = 1;
        char *ptr = "Sample string";  // Stored in Data segment
        if (ac == 2)
        {
                str = malloc(len(av[1]) + 1);
                strcpy(str, av[1]);
        }

        printf("The address of %s is %p\n",ptr,ptr);
        while (i)

        {
                printf("[%d] %s - addr: %p\n", i, str, str);
                sleep(1);
                i++;
        }
        free(str);
        return (0);
}

int len(char *str)
{
        int i;

        for (i = 0; str[i]; i++)
                ;
        return (i);
}

现在我制作了另一个程序来查看另一个程序的内存(尤其是堆栈),并使用 process_vm_readv 读取数据。当我打印这个进程的堆栈时,我得到了所有这些信息:进程被称为tobe,我把它称为./tobe "Yo Boys"

=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36/home/mohit05/code2/

如果上面的内容不可读,这里是另一个副本: 我怀疑所有这些变量和数据是否都存储在堆栈本身中,或者我是否正在运行到其他内存。 我使用/proc/{pid}/maps 获得了堆栈范围,然后使用process_vm_readv 读取了整个堆栈范围

【问题讨论】:

    标签: c linux stack kernel


    【解决方案1】:

    在现代 Linux 系统上,环境值是存储在堆栈中的“种类”——对于“种类”的特定值。

    构成环境的实际字符串与其他环境数据一起存储在进程虚拟地址空间的顶部(编号最高的地址)。正确的堆栈在此下方开始。内核的程序加载器将各个环境变量的地址连同argcargv 值一起压入堆栈。

    环境和堆栈之间的这种密切对应导致许多作者谈论环境“在堆栈上”,尽管严格来说,只有特定环境值的地址正确地在堆栈上。 Linux 进程地址空间的图表通常显示内存顶部的堆栈,但如果您在进程上运行pmap,您会发现通常情况并非如此——上面会有一两个段堆栈正确,环境变量将在其中之一中找到。

    【讨论】:

    • 那么基于此,我可以肯定地说我提取的数据来自进程堆栈本身?我一直怀疑我是否正在阅读堆栈以外的其他地方。
    • 我不知道。如果你从堆栈向上读取,你最终会到达环境。是否仍在堆栈中读取取决于堆栈顶部的位置。
    • 例如:7ffffe662000-7ffffe683000 rw-p 00000000 00:00 0 [stack] 是我从proc/pid/maps 获得的地址范围,我只在读取这个范围。如果有任何帮助,您希望我分享我正在阅读的程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 2016-03-18
    相关资源
    最近更新 更多