gdb跟踪调试进程的描述和创建
一、进程描述-提纲挈领
1.1 内存管理、文件系统、信号和进程间通信等概念和内容串起来。
-
进程控制块-PCB。
-
进程描述符
1.2 数据结构struct task_struct
示例代码:
结构体中包含了很多各种各样的进程控制文件如state进程状态,stack堆栈结构示意图如下。
1.3 Linux进程状态
Linux进程状态和操作系统进程状态这两者之间很不一样。
- 运行态
- 就绪态
- 堵塞态
三者之间的关系如图:
而Linux中TASK_RUNNING既有可能是就绪态又有可能是运行态,这就和操作系统原理不同,而原因就是Linux内核中TASK_RUNNING态只是表示了它可能获得CPU控制权,一旦获得那就是运行态,没获得就是就绪态处于被调度状态。
进程标识符:
pid_t pid;
pid-t tpid;
双向链表:
struct list_head tasks;
struct list_head{
strcut list_head *next,*prev;
}
示意图如下:
1.4 进程的创建之父子兄弟关系
父进程--real_parent、parent
子进程--struct list_head children
兄弟进程--struct list_head sibling
示意图如下:
实验过程
本周的实验不光了解进程创建还需要跟踪分析进程创建的过程。
下面开始正式的实验步骤
执行以下代码:
ls
cd ~/LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
mv test_fork.c test.c
make rootfs //主要功能在于编译增加了fork文件
运行截图:
等待一段时间后qemu窗口中编译过程也执行完成:
输入多次fork命令看是否成功调用:
启动gdb准备跟踪调试内核程序:
加载内核及端口:
file linux-3.18.6/vmlinux
target remote:1234
在Linux内核中设置内核函数断点:
b sys_clone
b do_fork
b dup_task_struct
b copy_process
b copy_thread
b ret_from_fork
继续运行内核程序,在代码行中输入c,会找到设置的第一个断点do_fork。:
在输入n或s进行单步调试(值得注意的是n执行会把执行的源程序中的函数调用一块执行,而s则不会)。
继续找到剩余的几个断点,对其进行跟踪。
总结:
刚开始我打算在自己虚拟机上进行实验虽然自己配备的3.9.4系统内核和实验楼上的不一样,但是本质上应该还是没问题的,问题可能出在以前改动过系统内核吧,也不清楚。于是只好继续用实验楼动不动死机的环境。吐槽一下光是这几行代码运行到最后一步的时候就卡住了。
ls
cd ~/LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
mv test_fork.c test.c
make rootfs
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
可能是同时开两个内核页面对他来说压力太大了吧。每次都只能删除实验环境重新敲代码,耗费了不少时间。