基于Linux-3.9.4内核的GDB跟踪系统调用实验
382 + 原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/
一、实验环境
win10 -> VMware -> Ubuntu16.04 + GDB -> QEMU -> linux-3.9.4 + MenuOS
二、实验目的
1、了解glibc提供的系统调用函数API,int 0x80、系统调用号及参数传递过程
2、了解保现场和恢复现场的过程
3、使用库函数API和C代码中嵌入式汇编代码两种方式使用同一个系统调用
3、分析system_call中断处理过程
三、实验过程及结果
1、系统内核及系统调用函数的选取
按照实验要求,本次实验需要采用的内核为kernel-5.0版本,在本人实际的实验过程中,一直出现GDB添加断点成功,但是程序运行时并未在断点处停止的现象,经过多次尝试无果之后,决定暂且先使用kernel-3.9.4.的内核,详细问题需要之后解决。
按照实验要求,对于系统调用函数的选取,应该选取和学号末尾数字相同的系统调用,经过查询之后,基于kernel-3.9.4的系统调用中,未含系统调用号为382的系统调用(arch:x86),决定暂且先使用系统调用号为20的系统调用sys_getpid。

图 1 系统调用号最大为350

图 2 系统调用号为20的sys_getpid
2、库函数API和C代码中嵌入式汇编代码两种方式对系统调用的实现
2.1 库函数API的实现

图 3 基于库函数API对sys_getpid的调用实现
需要注意的是,在调用getpid()函数时,需要加上对头文件的引用申明"#include <unistd.h>",不然可能编译阶段出现失败。
2.2 C代码中嵌入式汇编代码的实现

图 4 基于嵌入式汇编的方式对sys_getpid的调用实现
在上图中,立即数$0x14为sys_getpid在相应的系统调用表中的偏移量(20),"int $0x80\n\t",该语句的作用是触发系统调用中断,跳转至系统调用入口处。
3、对应两种方式的GDB跟踪
3.1 环境搭建的大致流程
在搭建实验环境的时候,需要准备的软件环境有:QEMU、GDB、内核的压缩镜像、根文件系统。
在内核镜像的make过程中,首先先执行“make i386_defconfig”,之后再使用"make menuconfig",基于界面对编译进行配置,为了使得GDB能够跟踪到内核的调试信息,需要选中kernel hacking ->compile the kernel with debug info一栏。保存退出,执行make。
根文件系统的制作,过程相对比较容易理解,对着相关教程执行问题并不大,这里就不再赘述。
在QEMU模拟过程中,对于GDB的参数设置,具体为:"file linux-3.9.4/vmlinux"、"target remote:1234"。
3.2 断点设置

图 5 设置的两个端点断点信息

图 6 MenuOS支持的命令
3.3 对基于库函数API方式实现过程的跟踪
在MenuOS命令行下输入mysyscall,会发现其在相应的断点处停止。

图 7 执行getpid()被中断

图 8 进入kernel/timer.c中的SYSCALL_DEFINE0(getpid)函数

图 9 进入arch/x86/include/asm/current.h

图 10 进入inlude/linux/sched.h,之后进入kernel/pid.c

图 11 SYSCALL_DEFINE0(getpid)函数返回
在这时候,GDB继续跟踪的话,效果不明显,经常性出现“Cannot find bounds of current function”,GDB对汇编指令的跟踪效果并不是很好。
3.4 对基于嵌入式汇编方式实现过程的跟踪
在MenuOS命令行下输入mysyscall_asm,会发现其在相应的断点处停止。

图 12 执行被断点1中断

图 13 断点1上下文

图 14 继续执行,停止在断点2,之后的过程与3.3小节内容相似

图 15 两次运行的结果
四、问题与总结
1、问题
在实际的实验过程中,对于mysyscall函数以及mysyscall_asm函数的执行,在第一次执行的时候均可以在断点处停止运行,之后的执行就会无视断点,直接运行结束。对于这个问题,目前的想法是可能对GDB的使用并不是很熟悉。
在实验kernel-5.0的时候,在使用GDB进行调试的过程中,出现一些问题,在解决大部分问题之后,卡在了其中的一个问题之上。

图 16 GDB连接失败(已按照提示解决)

图 17 GDB连接失败(未解决)
对于图17的错误,目前的想法是:可能是配套的python版本不对,在对应的./gdbinit文件中,多次尝试修改失败。
2、总结
对于system_call的过程,其源码如下。
RING0_INT_FRAME # can't unwind into user space anyway
ASM_CLAC
pushl_cfi %eax # save orig_eax
SAVE_ALL
GET_THREAD_INFO(%ebp)
# system call tracing in operation emulation
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmpl $(NR_syscalls), %eax
jae syscall_badsys
syscall_call:
call *sys_call_table(,%eax,4)
movl %eax,PT_EAX(%esp) # store the return value
syscall_exit:
LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
TRACE_IRQS_OFF
movl TI_flags(%ebp), %ecx
testl $_TIF_ALLWORK_MASK, %ecx # current->work
jne syscall_exit_work
TRACE_IRQS_IRET
restore_all_notrace:
movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
# Warning: PT_OLDSS(%esp) contains the wrong/random values if we
# are returning to the kernel.
# See comments in process.c:copy_thread() for details.
movb PT_OLDSS(%esp), %ah
movb PT_CS(%esp), %al
andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
CFI_REMEMBER_STATE
je ldt_ss # returning to user-space with LDT SS
restore_nocheck:
INTERRUPT_RETURN

基于Linux-3.9.4内核的GDB跟踪系统调用实验的更多相关文章
- linux内核分析第五次实验
给MenuOS增加time和time-asm命令 上周是从用户态的观点来理解系统调用,这周从内核态出发研究系统调用,通过跟踪调试,首先把上周的两个命令加到MenuOS中: rm menu -rf 强制 ...
- Linux内核分析-使用gdb跟踪调试内核从start_kernel到init进程启动
姓名:江军 ID:fuchen1994 实验日期:2016.3.13 实验指导 使用实验楼的虚拟机打开shell cd LinuxKernel/ qemu -kernel linux-3.18.6/a ...
- Linux系统启动那些事—基于Linux 3.10内核【转】
转自:https://blog.csdn.net/shichaog/article/details/40218763 Linux系统启动那些事—基于Linux 3.10内核 csdn 我的空间的下载地 ...
- 基于linux内核包过滤技术的应用网关
目录 基于linux内核包过滤技术的应用网关 硬件形态 基本原理 应用场景 主要功能 其他功能 客户定制 基于linux内核包过滤技术的应用网关 硬件形态 基本原理 应用场景 媒体内容过滤和深度识别 ...
- 现在的 Linux 内核和 Linux 2.6 的内核有多大区别?
作者:larmbr宇链接:https://www.zhihu.com/question/35484429/answer/62964898来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...
- 基于Linux平台的libpcap源码分析和优化
目录 1..... libpcap简介... 1 2..... libpcap捕包过程... 2 2.1 数据包基本捕包流程... 2 2.2 libpcap捕包过程... ...
- Linux内核分析之扒开系统调用的三层皮(下)
一.实验内容 1. 通过内核的方式使用系统调用 需要使用的命令 rm menu -rf //强制删除当前menugit clone http://github.com/mengning/menu.gi ...
- 高性能Linux服务器 第10章 基于Linux服务器的性能分析与优化
高性能Linux服务器 第10章 基于Linux服务器的性能分析与优化 作为一名Linux系统管理员,最主要的工作是优化系统配置,使应用在系统上以最优的状态运行.但硬件问题.软件问题.网络环境等 ...
- Linux内核学习笔记1——系统调用原理【转】
1什么是系统调用 系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口.用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文 ...
随机推荐
- emacs技巧
Table of Contents "ctrl space"设置mark 同时在选中的各行行首添加相同内容 寄存器 跳转到某行 删除光标所在的空格和TAB或空白行 把TAB全部转换 ...
- leetcode python 041首个缺失正数
##限定时间复杂度O(n)num=[0,5,3,1,2,-2,4,8,5,6]num=set(num)d=1for i in range(1,len(num)+1): if d in num: ...
- [2003_p1]乒乓球
一道因为输出不一样疯狂超时的题目(是我太菜,但是我jio得代码是ok的) 题目描述 国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及.其中11分制改革引起了很大的 ...
- 前段学习的roadmap
引自http://www.cnblogs.com/IMxinu/p/9693041.html
- Oracle入门之对表内容的dml操作
oracle表的管理--添加数据 使用insert语句向表中插入数据 插入数据基本语法: insert into table[(column [,column...])] values(value [ ...
- Eclipse如何新建TOMCAT并配置Server Locations和Publishing属性
Eclipse如何新建TOMCAT并配置Server Locations和Publishing属性 2018年05月08日 23:10:33 ACGkaka_ 阅读数:1269 一.建立TOMCA ...
- Mysql和Hadoop+Hive有什么关系?
1.Hive不存储数据,Hive需要分析计算的数据,以及计算结果后的数据实际存储在分布式系统上,如HDFS上. 2.Hive某种程度来说也不进行数据计算,只是个解释器,只是将用户需要对数据处理的逻辑, ...
- PTA-栈
1-1 若一个栈的输入序列为1,2,3,…,N,输出序列的第一个元素是i,则第j个输出元素是j−i−1. (2分) T F 作者: DS课程组 单位: 浙江大学 1-2 若一个栈的 ...
- 关于while read line 循环中变量作用域的问题
前一阵用shell写了一个从数据库中抽取数据生成.xml文件的脚本,要求是每个文件中只生成1000条数据.于是用到了while read line 作为循环. 在制作文件计数器的时候发现了一个问题,在 ...
- Spring学习札记(一)
写在前面:spring的两大特点:IOC与aop.IOC(Inverse of Control):控制反转,也可以称为依赖倒置.降低耦合.AOP:即面向切面编程. 从Spring的角度看,AOP最大的 ...