我试图调试物理内存分配,以了解Linux内核的哪个部分在x86-64上使用memblock_alloc_range_nid以及如何使用memblock_alloc_range_nid.

我运行的是最新的Linux Kernel 5.19-rc2台从upstream 建造的,在QEMU内部有Ubuntu 20.04台.问题是无法访问功能memblock_alloc_range_nid所在的存储器地址.而其他内核函数可以很容易地进行反汇编.

以下是我的gdb个连接到QEMU虚拟机中的内容:

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

memblock_alloc_range_nid函数有什么问题?为什么无法访问其地址?似乎memblock.c中的所有功能都无法访问.

推荐答案

MargaretRoi在上述注释中所述,memblock_alloc_range_nid()__init注释.只有在启动后的内核初始化期间,才需要使用__init__head和类似宏注释的函数.内核完成初始化后,包含所有这些函数的特殊内存部分将从内存中取消映射,因为它们不再需要.

如果要调试任何此类函数,必须很早中断,例如在start_kernel()时,然后可以判断该函数或设置断点并执行continue次以命中它.

重要提示:在QEMU命令行选项中添加-S(大写),使其在启动内核之前停止并等待调试器,并在使用-append "nokaslr"禁用KASLR的情况下启动内核(如果已经指定-append,则添加nokaslr).

以下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

启动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
   ...

C++相关问答推荐

intellisense不工作,甚至已经下载了c/c++扩展

如何正确地索引C中的 struct 指针数组?

如何在IF语句中正确使用0.0

正确的TCP/IP数据包 struct

Char变量如何在不使用方括号或花括号的情况下存储字符串,以及它如何迭代到下一个字符?

S将C语言宏定义为自身的目的是什么?(在glibc标题中看到)

在创建动态泛型数组时,通过realloc对故障进行分段

C指针概念分段故障

如何使用C++在控制台中以彩色打印被阻止的客户端

OpenSSL:如何将吊销列表与SSL_CTX_LOAD_VERIFY_LOCATIONS一起使用?

指向不同类型的指针是否与公共初始序列规则匹配?

我在反转双向链表时遇到问题

不使用任何预定义的C函数进行逐位运算

正在try 理解C++中的`正在释放的指针未被分配‘错误

变量值不正确的问题

UpDown控制与预期相反

我错误地修复了一个错误,想了解原因

如何在Rust中处理C的longjmp情况?

中位数和众数不正确

可以从指针数组中的值初始化指针吗?