PostgreSQL 原始碼解讀(227)- Linux Kernel(程式虛擬記憶體#2)
PostgreSQL使用程式架構,每個連線對應一個後臺程式,為了更好的理解這種架構,有必要深入理解程式的相關知識.本節主要介紹了Linux下的程式虛擬記憶體結構,並以使用C語言樣例程式進行說明.
一、虛擬記憶體
程式虛擬記憶體的詳細結構如下圖所示:
C樣例程式如下:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/**
* f - print locations of various elements
*
* Returns: nothing
*/
void f(void)//子函式
{
int a;
int b;
int c;
a = 98;
b = 1024;
c = a * b;
printf("[f] a = %d, b = %d, c = a * b = %d\n", a, b, c);
printf("[f] Adresses of a: %p, b = %p, c = %p\n", (void *)&a, (void *)&b, (void *)&c);
}
/**
* main - print locations of various elements
*
* Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
*/
int main(int ac, char **av, char **env)
{
int a;//本地變數,位於棧中
void *p;//指標,在堆中分配記憶體
int i;
int size;
printf("Address of a: %p\n", (void *)&a);
p = malloc(98);//在堆中分配記憶體
if (p == NULL)
{
fprintf(stderr, "Can't malloc\n");
return (EXIT_FAILURE);
}
printf("Allocated space in the heap: %p\n", p);
printf("Address of function main: %p\n", (void *)main);//main函式所在的記憶體地址
printf("First bytes of the main function:\n\t");
for (i = 0; i < 15; i++)
{
printf("%02x ", ((unsigned char *)main)[i]);//首16個位元組
}
printf("\n");
printf("Address of the array of arguments: %p\n", (void *)av);//輸入引數陣列地址
printf("Addresses of the arguments:\n\t");//
for (i = 0; i < ac; i++)
{
printf("[%s]:%p ", av[i], av[i]);//列印輸入引數
}
printf("\n");
printf("Address of the array of environment variables: %p\n", (void *)env);//環境變數地址
printf("Address of the first environment variables:\n");//環境變數資訊
for (i = 0; i < 3; i++)
{
printf("\t[%p]:\"%s\"\n", env[i], env[i]);
}
/* size of the env array */
i = 0;
while (env[i] != NULL)//以NULL作為終結
{
i++;
}
i++; /* the NULL pointer */
size = i * sizeof(char *);
printf("Size of the array env: %d elements -> %d bytes (0x%x)\n", i, size, size);//計算環境變數陣列大小
f();//呼叫函式
getchar();//接受輸入,程式不退出
return (EXIT_SUCCESS);
}
編譯並執行
[root@localhost hacker]# gcc -Wall -Wextra -Werror main-7.c -o 7
[root@localhost hacker]# ./7 Hello Hacker Jack!
Address of a: 0x7fff5b327bb8 --> 位於棧中
Allocated space in the heap: 0x9b6010 --> 位於堆中
Address of function main: 0x400729 --> 可執行檔案
First bytes of the main function:
55 48 89 e5 48 83 ec 40 89 7d dc 48 89 75 d0
Address of the array of arguments: 0x7fff5b327cb8 -->引數陣列地址
Addresses of the arguments:
[./7]:0x7fff5b329808 [Hello]:0x7fff5b32980c [Hacker]:0x7fff5b329812 [Jack!]:0x7fff5b329819 --> 輸入引數
Address of the array of environment variables: 0x7fff5b327ce0 --> 環境變數陣列
Address of the first environment variables:
[0x7fff5b32981f]:"XDG_SESSION_ID=1"
[0x7fff5b329830]:"HOSTNAME=localhost.localdomain"
[0x7fff5b32984f]:"SELINUX_ROLE_REQUESTED="
Size of the array env: 27 elements -> 216 bytes (0xd8)
[f] a = 98, b = 1024, c = a * b = 100352
[f] Adresses of a: 0x7fff5b327b7c, b = 0x7fff5b327b78, c = 0x7fff5b327b74 --> 函式f中的變數地址
通過udis86可反編譯,得到彙編程式碼
[root@localhost install]# echo "55 48 89 e5 48 83 ec 10 48 8d 45 f0 48 89 c6" | udcli -64 -x -o 400729
0000000000400729 55 push rbp
000000000040072a 4889e5 mov rbp, rsp
000000000040072d 4883ec10 sub rsp, 0x10
0000000000400731 488d45f0 lea rax, [rbp-0x10]
0000000000400735 4889c6 mov rsi, rax
[root@localhost install]#
檢視該程式的記憶體對映資訊
[root@localhost install]# ps aux | grep "./7" | grep -v grep
root 6471 0.0 0.0 4348 348 pts/0 S+ 15:24 0:00 ./7 Hello Hacker Jack!
[root@localhost install]# cat /proc/6471/maps
00400000-00401000 r-xp 00000000 fd:00 134287606 /data/source/hacker/7
00600000-00601000 r--p 00000000 fd:00 134287606 /data/source/hacker/7
00601000-00602000 rw-p 00001000 fd:00 134287606 /data/source/hacker/7
009b6000-009d7000 rw-p 00000000 00:00 0 [heap]
7f95b5d16000-7f95b5ed8000 r-xp 00000000 fd:00 151914 /usr/lib64/libc-2.17.so
7f95b5ed8000-7f95b60d8000 ---p 001c2000 fd:00 151914 /usr/lib64/libc-2.17.so
7f95b60d8000-7f95b60dc000 r--p 001c2000 fd:00 151914 /usr/lib64/libc-2.17.so
7f95b60dc000-7f95b60de000 rw-p 001c6000 fd:00 151914 /usr/lib64/libc-2.17.so
7f95b60de000-7f95b60e3000 rw-p 00000000 00:00 0
7f95b60e3000-7f95b6105000 r-xp 00000000 fd:00 151907 /usr/lib64/ld-2.17.so
7f95b62f8000-7f95b62fb000 rw-p 00000000 00:00 0
7f95b6301000-7f95b6304000 rw-p 00000000 00:00 0
7f95b6304000-7f95b6305000 r--p 00021000 fd:00 151907 /usr/lib64/ld-2.17.so
7f95b6305000-7f95b6306000 rw-p 00022000 fd:00 151907 /usr/lib64/ld-2.17.so
7f95b6306000-7f95b6307000 rw-p 00000000 00:00 0
7fff5b309000-7fff5b32a000 rw-p 00000000 00:00 0 [stack]
7fff5b3f1000-7fff5b3f3000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
[root@localhost install]#
二、參考資料
Virtual memory
Hack the Virtual Memory: drawing the VM diagram
Udis86
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6906/viewspace-2657278/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL 原始碼解讀(226)- Linux Kernel(虛擬記憶體)SQL原始碼Linux記憶體
- PostgreSQL 原始碼解讀(229)- Linux Kernel(程式虛擬記憶體#3)SQL原始碼Linux記憶體
- Linux 虛擬記憶體Linux記憶體
- 鴻蒙輕核心原始碼分析:虛擬記憶體鴻蒙原始碼記憶體
- Linux 虛擬記憶體引數配置Linux記憶體
- 詳細理解Linux虛擬記憶體Linux記憶體
- 虛擬記憶體有什麼用 虛擬記憶體不足怎麼解決記憶體
- PostgreSQL 原始碼解讀(115)- 後臺程式#3(checkpointer程式#2)SQL原始碼
- PostgreSQL 原始碼解讀(114)- 後臺程式#2(checkpointer程式#1)SQL原始碼
- PostgreSQL 原始碼解讀(236)- 後臺程式#14(autovacuum程式#2)SQL原始碼
- 為什麼 Linux 需要虛擬記憶體Linux記憶體
- linux伺服器增加虛擬記憶體Linux伺服器記憶體
- Flutter引擎原始碼解讀-記憶體管理篇Flutter原始碼記憶體
- 聊聊虛擬記憶體記憶體
- 虛擬記憶體系統——瞭解記憶體的工作原理記憶體
- linux kernel記憶體碎片防治技術Linux記憶體
- PostgreSQL 原始碼解讀(154)- 後臺程式#6(walsender#2)SQL原始碼
- PostgreSQL 原始碼解讀(2)- 插入資料#2(RelationPutHeapTuple)SQL原始碼APT
- ThreadLocal原始碼解讀和記憶體洩露分析thread原始碼記憶體洩露
- 解密虛擬 DOM——snabbdom 核心原始碼解讀解密原始碼
- 【Java基礎】實體記憶體&虛擬記憶體Java記憶體
- 5.虛擬記憶體記憶體
- 淺析Linux Kernel[5.11.0]記憶體管理(一)Linux記憶體
- Linux記憶體不夠了?看看如何開啟虛擬記憶體增加記憶體使用量Linux記憶體
- 讀書筆記】《PostgreSQL指南-內幕探索》-2.程式和記憶體架構筆記SQL記憶體架構
- JVM原始碼分析之堆外記憶體完全解讀JVM原始碼記憶體
- 【原創】Linux虛擬化KVM-Qemu分析(五)之記憶體虛擬化Linux記憶體
- PostgreSQL 原始碼解讀(3)- 如何閱讀原始碼SQL原始碼
- Linux設定虛擬記憶體教學和實戰Linux記憶體
- 虛擬記憶體(待補充)記憶體
- PostgreSQL 原始碼解讀(117)- MVCC#2(獲取快照#2)SQL原始碼MVCC#
- Java虛擬機器記憶體區域詳解Java虛擬機記憶體
- win10虛擬記憶體怎麼設定 win10虛擬記憶體設定步驟詳解Win10記憶體
- 記憶體管理兩部曲之虛擬記憶體管理記憶體
- win10怎樣刪虛擬記憶體_Win10虛擬記憶體如何關閉Win10記憶體
- PostgreSQL 原始碼解讀(231)- 查詢#124(NOT IN實現#2)SQL原始碼
- PostgreSQL 原始碼解讀(193)- 查詢#109(排序#2 - ExecSort)SQL原始碼排序
- PostgreSQL 原始碼解讀(250)- PG 14(Improving connection scalability)#2SQL原始碼