使用 GDB 检查映射地址 [英] Examining mmaped addresses using GDB

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

问题描述

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

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".

有没有办法告诉GDB这块内存可以查看?或者,我可以在 mmap 中做些什么不同的事情(调用或 foo_mmap 的实现)来允许它访问这个内存?

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?

请注意,我不是在询问/dev/mem(如第一个片段中那样),而是询问通过 ioremap()、virt_to_phys() 和 remap_pfn_range() 获取的内存的 mmap

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()

推荐答案

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

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...
");
        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.
", (unsigned long) mptr);
    printf("mptr points to 0x%lX. *mptr = 0x%X
", (unsigned long) mptr,
           *mptr);
    mptr[0] = 'a';
    mptr[1] = 'b';
    printf("mptr points to 0x%lX. *mptr = 0x%X
", (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天全站免登陆