使用GDB检查虚拟地址 [英] Examining mmaped addresses using GDB

查看:215
本文介绍了使用GDB检查虚拟地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是我在 Linux中直接访问内存中发布的驱动程序将一些物理内存映射到用户空间地址。但是,我不能使用GDB来查看任何地址;即x 0x12345678(其中0x12345678是mmap的返回值)失败,并显示错误无法访问地址0x12345678处的内存。

有什么办法可以告诉GDB这个内存可以被查看?或者,我可以在mmap中做些什么不同的事情(无论是调用还是执行foo_mmap),这将允许它访问此内存?



请注意,我'm不会询问/ dev / mem(就像在第一个片段那样),而是关于通过ioremap(),virt_to_phys()和remap_pfn_range()获取的内存的mmap

解决方案

我相信Linux不会通过ptrace()访问I / O内存。你可以编写一个简单地读取mmap地址并使gdb调用它的函数。这里是foo-user.c程序的一个稍微修改过的版本,以及gdb会话的输出。

SYS / stat.h>
#include< fcntl.h>
#include< unistd.h>
#include< stdio.h>
#include< sys / mman.h>

char * mptr;

char peek(int offset)
{
return mptr [offset];
}

int main(void)
{
int fd;
fd = open(/ dev / foo,O_RDWR | O_SYNC);
if(fd == -1){
printf(open error ... \\\
);
返回1;
}
mptr = mmap(0,1 * 1024 * 1024,PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED,fd,4096);
printf(On start,mptr points to 0x%lX.\\\
,(unsigned long)mptr);
printf(mptr指向0x%lX。* mptr = 0x%X \ n,(unsigned long)mptr,
* mptr);
mptr [0] ='a';
mptr [1] ='b';
printf(mptr指向0x%lX。* mptr = 0x%X \ n,(unsigned long)mptr,
* mptr);
close(fd);
返回0;



$ b $ make foo-user CFLAGS = -g
$ gdb -q foo-user
(gdb)break 27
在0x804855f处的断点1:file foo-user.c,第27行。
(gdb)run
启动程序:/ home / me / foo / foo-user
启动,mptr指向0xB7E1E000。
mptr指向0xB7E1E000。 * mptr = 0x61

断点1,main()在foo-user.c:27
27 mptr [0] ='a';
(gdb)n
28 mptr [1] ='b';
(gdb)print peek(0)
$ 1 = 97'a'
(gdb)print peek(1)
$ 2 = 98'b'


I'm using the driver I posted at Direct Memory Access in Linux to mmap some physical ram into a userspace address. However, I can't use GDB to look at any of the address; i.e., x 0x12345678 (where 0x12345678 is the return value of mmap) fails with an error "Cannot access memory at address 0x12345678".

Is there any way to tell GDB that this memory can be viewed? Alternatively, is there something different I can do in the mmap (either the call or the implementation of foo_mmap there) that will allow it to access this memory?

Note that I'm not asking about /dev/mem (as in the first snippet there) but about a mmap to memory acquired via ioremap(), virt_to_phys() and remap_pfn_range()

解决方案

I believe Linux does not make I/O memory accessible via ptrace(). You could write a function that simply reads the mmap'ed address and have gdb invoke it. Here's a slightly modified version of your foo-user.c program along with the output from a gdb session.

#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>

char *mptr;

char peek(int offset)
{
    return mptr[offset];
}

int main(void)
{
    int fd;
    fd = open("/dev/foo", O_RDWR | O_SYNC);
    if (fd == -1) {
        printf("open error...\n");
        return 1;
    }
    mptr = mmap(0, 1 * 1024 * 1024, PROT_READ | PROT_WRITE,
             MAP_FILE | MAP_SHARED, fd, 4096);
    printf("On start, mptr points to 0x%lX.\n", (unsigned long) mptr);
    printf("mptr points to 0x%lX. *mptr = 0x%X\n", (unsigned long) mptr,
           *mptr);
    mptr[0] = 'a';
    mptr[1] = 'b';
    printf("mptr points to 0x%lX. *mptr = 0x%X\n", (unsigned long) mptr,
           *mptr);
    close(fd);
    return 0;
}



$ make foo-user CFLAGS=-g
$ gdb -q foo-user
(gdb) break 27
Breakpoint 1 at 0x804855f: file foo-user.c, line 27.
(gdb) run
Starting program: /home/me/foo/foo-user 
On start, mptr points to 0xB7E1E000.
mptr points to 0xB7E1E000. *mptr = 0x61

Breakpoint 1, main () at foo-user.c:27
27          mptr[0] = 'a';
(gdb) n
28          mptr[1] = 'b';
(gdb) print peek(0)
$1 = 97 'a'
(gdb) print peek(1)
$2 = 98 'b'

这篇关于使用GDB检查虚拟地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆