[英]Linux Kernel function memblock_alloc_range_nid is not presented in the address space
I'm trying to debug physical memory allocation to understand what part of the Linux Kernel use memblock_alloc_range_nid on x86-64
and how.我正在尝试调试物理内存分配以了解 Linux 内核的哪些部分在x86-64
上使用memblock_alloc_range_nid以及如何使用。
I'm running the latest Linux Kernel 5.19-rc2
built from upstream with Ubuntu 20.04
inside QEMU.我正在使用 QEMU 中的Ubuntu 20.04
运行从上游构建的最新Linux Kernel 5.19-rc2
。 The problem is it's not possible to access memory address the function memblock_alloc_range_nid
is located at.问题是无法访问函数memblock_alloc_range_nid
所在的内存地址。 While other Kernel functions can be easily disassembled.而其他内核功能可以很容易地反汇编。
Here is what I have in my gdb
connected to the QEMU VM:这是我的gdb
中连接到 QEMU VM 的内容:
(gdb) disas memblock_alloc_range_nid
Cannot access memory at address 0xffffffff831a05d1
(gdb) disas native_safe_halt
Dump of assembler code for function native_safe_halt:
#...
End of assembler dump.
What's wrong with the function memblock_alloc_range_nid
?函数memblock_alloc_range_nid
有什么问题? Why is it not possible to access its address?为什么无法访问其地址? It seems all the function frommemblock.c
cannot be accessed.似乎无法访问memblock.c
中的所有功能。
As Margaret and Roi have noted in the above comments, memblock_alloc_range_nid()
is annotated with __init
.正如Margaret和Roi在上述评论中所指出的, memblock_alloc_range_nid()
使用__init
进行注释。 Functions annotated with __init
, __head
and similar macros are only needed during kernel initialization right after boot.使用__init
、 __head
和类似宏注释的函数仅在启动后内核初始化期间才需要。 After the kernel has finished initializing things, the special memory section containing all those functions is unmapped from memory since they are not needed anymore.在内核完成初始化之后,包含所有这些函数的特殊内存部分将从内存中取消映射,因为不再需要它们。
If you want to debug any such function, you will have to break very early, for example at start_kernel()
, then you can inspect the function or set a breakpoint and continue
execution to hit it.如果要调试任何此类函数,则必须尽早中断,例如在start_kernel()
处,然后您可以检查该函数或设置断点并continue
执行以命中它。
Important: add -S
(uppercase) to your QEMU command line options to make it stop and wait for the debugger before starting the kernel, and start the kernel with KASLR disabled using -append "nokaslr"
(or adding nokaslr
if you are already specifying -append
).重要提示:在 QEMU 命令行选项中添加-S
(大写)以使其在启动内核之前停止并等待调试器,并在禁用 KASLR 的情况下使用-append "nokaslr"
启动内核(如果您已经指定,则添加nokaslr
- -append
)。
The following GDB script should be what you need:以下 GDB 脚本应该是您需要的:
$ cat script.gdb
directory /path/to/kernel-source-dir
file /path/to/kernel-source-dir/vmlinux
target remote localhost:1234
break start_kernel
continue
Launch gdb -x script.gdb
(after starting QEMU), and when you hit the start_kernel
breakpoint, you can add another one for memblock_alloc_range_nid
, then continue
:启动gdb -x script.gdb
(在启动 QEMU 之后),当你命中start_kernel
断点时,你可以为memblock_alloc_range_nid
添加另一个断点,然后continue
:
0x000000000000fff0 in exception_stacks ()
Breakpoint 1 at 0xffffffff82fbab4c
Breakpoint 1, 0xffffffff82fbab4c in start_kernel ()
(gdb) b memblock_alloc_range_nid
Breakpoint 2 at 0xffffffff82fe2879
(gdb) c
Continuing.
Breakpoint 2, 0xffffffff82fe2879 in memblock_alloc_range_nid ()
(gdb) disassemble
Dump of assembler code for function memblock_alloc_range_nid:
=> 0xffffffff82fe2879 <+0>: push r15
0xffffffff82fe287b <+2>: mov r15,rcx
0xffffffff82fe287e <+5>: push r14
0xffffffff82fe2880 <+7>: mov r14,rdx
0xffffffff82fe2883 <+10>: push r13
0xffffffff82fe2885 <+12>: mov r13d,r9
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.