Memory 检查pmap报告的虚拟内存块
我发现我的程序有漏洞。它没有被“valgrind memcheck”抓住(我通过总结报告确认了这一点,它没有接近我所能看到的最高使用率)。在使用“valgrind massif——pages as heap”时,我可以更接近我的内存使用情况。 然而,它并没有报告对执行mmap并分配大部分内存的部分的完整回溯,我也不能检查内存分配,因为我只能在程序终止后收集massif输出。 我尝试的另一件事是检查占用大量RSS空间的内存块。但是,我不知道如何查看pmap报告的内存块的内容。把那个地址放在gdb力帮助上。我听说gdb使用了一些地址随机化。有人能帮助我如何获得与pmap输出报告的内存位置相对应的符号吗 把那个地址放在gdb力帮助上 我不知道你所说的“把那个地址放在gdb上”是什么意思,但正确地这样做会有所帮助 我听说gdb使用了一些地址随机化 你听错了:GDB本身不做任何随机化,它(默认情况下)禁用操作系统执行的随机化,以便使调试更容易和更具可复制性 有人能帮助我如何获得与pmap输出报告的内存位置相对应的符号吗 您感到困惑:堆分配的内存定义上没有任何符号 好的,让我们来看一个使用GDB检查在Memory 检查pmap报告的虚拟内存块,memory,gdb,massif,Memory,Gdb,Massif,我发现我的程序有漏洞。它没有被“valgrind memcheck”抓住(我通过总结报告确认了这一点,它没有接近我所能看到的最高使用率)。在使用“valgrind massif——pages as heap”时,我可以更接近我的内存使用情况。 然而,它并没有报告对执行mmap并分配大部分内存的部分的完整回溯,我也不能检查内存分配,因为我只能在程序终止后收集massif输出。 我尝试的另一件事是检查占用大量RSS空间的内存块。但是,我不知道如何查看pmap报告的内存块的内容。把那个地址放在gdb力
pmap
中可见的内存的例子。让我们从编译这个程序开始,它构建了一个100万长的链表,其中包含一些字符串:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
typedef struct Node { struct Node *next; char payload[64]; } Node;
int main()
{
int j;
Node *head = NULL;
for (j = 0; j < 1000000; j++) {
Node *n = malloc(sizeof(*n));
n->next = head;
sprintf(n->payload, "string %d", j);
head = n;
}
return 0;
}
gcc -Wall -g -std=c99 t.c && gdb -q ./a.out
(gdb) b 17
Breakpoint 1 at 0x4005e3: file t.c, line 17.
(gdb) r
Starting program: /tmp/a.out
Breakpoint 1, main () at t.c:17
17 return 0;
很明显,78MiB的anon
空间(从0x602000
开始)必须是大多数数据所在的位置。(您还可以通过在循环中单步执行几次来验证这一点。)
我们如何看待这些数据?像这样:
(gdb) x/30gx 0x602000
0x602000: 0x0000000000000000 0x0000000000000051
0x602010: 0x0000000000000000 0x3020676e69727473
0x602020: 0x0000000000000000 0x0000000000000000
0x602030: 0x0000000000000000 0x0000000000000000
0x602040: 0x0000000000000000 0x0000000000000000
0x602050: 0x0000000000000000 0x0000000000000051
0x602060: 0x0000000000602010 0x3120676e69727473
0x602070: 0x0000000000000000 0x0000000000000000
0x602080: 0x0000000000000000 0x0000000000000000
0x602090: 0x0000000000000000 0x0000000000000000
0x6020a0: 0x0000000000000000 0x0000000000000051
0x6020b0: 0x0000000000602060 0x3220676e69727473
0x6020c0: 0x0000000000000000 0x0000000000000000
0x6020d0: 0x0000000000000000 0x0000000000000000
0x6020e0: 0x0000000000000000 0x0000000000000000
您可以立即注意到,在0x602018
、在0x602068
和0x6020b8
中都有ASCII
字符串
您可以这样检查这些字符串:
(gdb) x/s 0x602018
0x602018: "string 0"
(gdb) x/s 0x602068
0x602068: "string 1"
(gdb) x/s 0x6020b8
0x6020b8: "string 2"
您还可以注意到,在0x602060
处有一个指向0x602010
的指针,在0x6020b0
处有一个指向0x602060
的指针
这让您猜测在0x602060
处有一个节点,在0x6020b0
处有另一个节点。你可以证实这个猜测:
(gdb) p *(Node*)0x602060
$1 = {next = 0x602010, payload = "string 1", '\000' <repeats 55 times>}
(gdb) p *(Node*)0x6020b0
$2 = {next = 0x602060, payload = "string 2", '\000' <repeats 55 times>}
(gdb)p*(节点*)0x602060
$1={next=0x602010,payload=“string 1”,'\000'}
(gdb)p*(节点*)0x6020b0
$2={next=0x602060,payload=“string 2”,'\000'}
这就是全部
(gdb) p *(Node*)0x602060
$1 = {next = 0x602010, payload = "string 1", '\000' <repeats 55 times>}
(gdb) p *(Node*)0x6020b0
$2 = {next = 0x602060, payload = "string 2", '\000' <repeats 55 times>}