局部变量的地址不在smaps所示的堆栈地址范围内

时间:2014-01-05 04:35:14

标签: c++ c linux memory gdb

我得到了一个进程的堆栈内存信息:

cat /proc/17647/smaps |grep stack

7ffff8840000-7ffff8853000 rwxp 7ffffffe9000 00:00 0                      [stack]

我只知道7ffff8840000-7ffff8853000是VM地址中堆栈段的起始和结束边界,第4列'7ffffffe9000'是第1列中显示的VM地址的起始RAM地址;映射关系由pagetable定义。

在这里,我有一个问题:此VM段中的第一个字节是否具有RAM地址7ffffffe9000?在这种情况下,我应该使用以下表达式将变量的VM地址(例如,x)获取到RAM地址:(x - 7ffff8840000)+ 7ffffffe9000

我在这个进程上运行gdb来查看一些局部变量的地址(只能在堆栈中),

gdb -p 17647
.....
b xx.cpp:100
....
p &var1
$2 = (int *) 0x4eb02a40

在这里,我有一个问题:var1是函数中的局部变量(不能错误),但其地址0x4eb02a40不在VM地址7ffff8840000之间 - 7ffff8853000, 也不是它附近的RAM地址7ffffffe9000因为0x4eb02a40远小于7ffffffe9000,所以,0x4eb02a40是VM地址还是RAM地址?如何获得 我的变量的真实RAM地址?

另一个问题:通过同时使用gdb和pmap或cat / proc / 17647 / smaps,如何判断变量地址是堆还是堆栈还是数据段?

1 个答案:

答案 0 :(得分:0)

  

var1是函数中的局部变量(不能错误),但其地址0x4eb02a40不在VM地址之间7ffff8840000-7ffff8853000

两种可能的解释。最有可能的一个:

  • 你的程序是多线程的,你在主线以外的线程中点击了断点。

每个线程都有自己的堆栈区域,libpthread.sommap获取。这样的映射在stack中没有/proc/self/maps - 就内核而言,这只是一个常规的匿名映射,并没有什么特别之处。

不太可能的一个:

  • 您的程序使用coroutine-style编程(可能使用makecontext,也许使用longjmp),并且您的断点位于在单独堆栈上执行的协程中。