我正在使用带有 ARM cortex_A9_MPCORE 处理器的开发板(雪球),运行带有 3.0.8+ 内核的 linux。我使用 GDB 和 openocd 进行调试。
我正在寻找一种方法来查找用户模式进程的地址空间,尤其是文本段和用户模式堆栈。
首先,我查看了 /proc/"PID"/maps,例如,我正在为一个正在运行的进程获取此输出:
# cat /proc/1124/maps
00008000-000d5000 r-xp 00000000 b3:02 181 /system/bin/lbsd
000d5000-000f8000 rw-p 000cd000 b3:02 181 /system/bin/lbsd
000f8000-0014a000 rw-p 00000000 00:00 0 [heap]
0014a000-0014c000 rw-p 00000000 00:00 0 [heap]
.
.
.
b0001000-b0009000 r-xp 00001000 b3:02 183 /system/bin/linker
b0009000-b000a000 rw-p 00009000 b3:02 183 /system/bin/linker
b000a000-b0015000 rw-p 00000000 00:00 0
bea00000-bea21000 rw-p 00000000 00:00 0 [stack]
ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors]
然后使用 GDB,我编写了一个脚本,从 init_task 开始解析板上运行的任务列表,对于每个任务,它获取在 task_struct 中找到的 mm_struct 的值,然后提取 start_code、end_code 和 start_stack 的值。最后,脚本解析 mmap 指向的不同内存区域。该脚本在开发板处于调试状态时运行,Cortex a9 的两个内核都已停止
这是与上述相同过程的 GDB 脚本的输出:
taskaddr 0xdf29f140
Name: lbsd
mm start text 8000
mm end text d4ba4
mm start stack bee63df0
####MEMORY REGIONS#####
vm_start 0x8000
vm_end 0xd5000
vm_flags 0x8001875
-----------------------
vm_start 0xd5000
vm_end 0xf8000
vm_flags 0x8101873
-----------------------
vm_start 0xf8000
vm_end 0x14a000
vm_flags 0x100073
-----------------------
vm_start 0x14a000
vm_end 0x14c000
vm_flags 0x100073
-----------------------
.
.
.
-----------------------
vm_start 0xb0001000
vm_end 0xb0009000
vm_flags 0x8000875
-----------------------
vm_start 0xb0009000
vm_end 0xb000a000
vm_flags 0x8100873
-----------------------
vm_start 0xb000a000
vm_end 0xb0015000
vm_flags 0x100073
-----------------------
vm_start 0xbee42000
vm_end 0xbee64000
vm_flags 0x100173
-----------------------
vm_start 0xffff0000
vm_end 0xffff1000
vm_flags 0x40c0055
-----------------------
除了堆栈之外,内存区域与所使用的两种方法都匹配,在 /proc 方法的输出中,它从 bea00000 开始,而在 mm_struct 的 start_stack 字段中,它位于 bee63df0,vm_struct 指向的内存区域指示 bee42000。有人可以解释这些值的区别吗?
我的第二个问题是关于 00008000 和 000d5000 之间的第一个内存区域的值,它对应于进程的文本部分。我注意到很多进程共享这些地址。内核如何设法获得文本内存区域的真实地址?