理解C++变量存储模型
作者:网络转载 发布时间:[ 2013/2/21 10:18:34 ] 推荐标签:
我们介绍了普通程序运行时在内存中的布局,下面我们专门针对C++源代码以WinDbg为工具分析下C++程序的变量存储模型。
下面我们尝试分析C++变量的存储模型, 我们的测试程序非常简单:
#include <iostream>
using namespace std;
const char* global_const_string = "hello world";
int global_int = 20;
static int global_static_int = 30;
int main()
{
static int local_static_int = 100;
int local_int = 200;
int* pValue = new int(300);
cout << global_const_string << global_int
<< global_static_int << local_static_int
<< local_int << *pValue;
delete pValue;
system("pause");
return 0;
}
可以看到我们上面对程序虽然简单,但是基本包括了所有的变量类型,包括静态的,常量的,全局的,本地的,还有new出来的,下面我们依次分析每个变量所属的存储区域。
我们直接用WinDbg以源码的方式调试我们的测试程序consoleTest.exe.
首先我们分析下consoleTest.exe模块的起始地址及内部数据节的分布情况,通过!address命令:
* 400000 401000 1000 MEM_IMAGE MEM_COMMIT PAGE_READONLY Image "ConsoleTest.exe"
|- 401000 41d000 1c000 MEM_IMAGE MEM_COMMIT PAGE_EXECUTE_READ Image "ConsoleTest.exe"
|- 41d000 422000 5000 MEM_IMAGE MEM_COMMIT PAGE_READONLY Image "ConsoleTest.exe"
|- 422000 426000 4000 MEM_IMAGE MEM_COMMIT PAGE_WRITECOPY Image "ConsoleTest.exe"
|- 426000 427000 1000 MEM_IMAGE MEM_COMMIT PAGE_READONLY Image "ConsoleTest.exe"
可以看到consoleTest.exe模块在内存中的起始地址是0x400000,接下来可以通过!dh 0x400000分析它内部的数据节分布,并且终我们可以得出如下结论:
地址 400000 - 401000 : PE文件头,属性是只读
地址 401000 - 41d000 : .text, 属性是只读可执行,表示代码节
地址 41d000 - 422000 : .rdata, 属性是只读, 表示只读数据
地址 422000 - 426000 : .data, 属性是写入时拷贝,表示可读写数据
地址 426000 - 427000 : .rsrc, 属性是只读,表示资源节
通过!address -f:stack命令我们可以看到:
0:000> !address -f:stack
BaseAddr EndAddr+1 RgnSize Type State Protect Usage
-------------------------------------------------------------------------------------------
40000 13d000 fd000 MEM_PRIVATE MEM_RESERVE Stack [8b0.1d0; ~0]
13d000 13e000 1000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE|PAGE_GUARD Stack [8b0.1d0; ~0]
13e000 140000 2000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Stack [8b0.1d0; ~0]
可以看到我们主线程的堆栈起始地址是:13e000 - 140000
接下来我们首先分析所有全局变量的存储区域,通过x consoletest!global*命令,让调试器列出所有在consoletest模块中global开头的调试符号:
0:000> x consoletest!global*
00422000 ConsoleTest!global_const_string = 0x0041d1dc "hello world"
00422004 ConsoleTest!global_int = 0n20
00422008 ConsoleTest!global_static_int = 0n30
004238a0 ConsoleTest!global_locale = 0x00000000
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11