2018-2019-1 20189205《Linux内核原理与分析》第六周作业

跟踪系统调用

调试MenuOS新增的函数

重新下载 menu.git可以看到 在test.c文件中增加了新的函数TimeTimeAsm

int Time(int argc, char *argv[])
{
    time_t tt;
    struct tm *t;
    tt = time(NULL);
    t = localtime(&tt);
    printf("time:%d:%d:%d:%d:%d:%d
",t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
    return 0;
}

int TimeAsm(int argc, char *argv[])
{
    time_t tt;
    struct tm *t;
    asm volatile(
        "mov $0,%%ebx
	"
        "mov $0xd,%%eax
	" 
        "int $0x80
	" 
        "mov %%eax,%0
	"  
        : "=m" (tt) 
    );
    t = localtime(&tt);
    printf("time:%d:%d:%d:%d:%d:%d
",t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
    return 0;
}

其调用接口分别为timetime-asm

    MenuConfig("time","Show System Time",Time);
    MenuConfig("time-asm","Show System Time(asm)",TimeAsm);

其功能为显示当前系统时间,
make rootfs 可以打开增加了新功能的MenuOS系统,在系统中使用新增的功能timetime-asm

gdb跟踪调试sys_time

在gdb中连接MenuOS的1234端口,对其中的time函数进行调试,查看其运行过程。由于其调用了系统调用sys_time对该系统调用进行跟踪,查看其调用的功能。

system_call

ENTRY(system_call)
     RING0_INT_FRAME    
     ASM_CLAC        
     pushl_cfi %eax            //保存系统调用号;
     SAVE_ALL                  //可以用到的所有CPU寄存器保存到栈中
     GET_THREAD_INFO(%ebp)     //ebp用于存放当前进程thread_info结构的地址
     testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
     jnz syscall_trace_entry
     cmpl $(nr_syscalls), %eax  //检查系统调用号(系统调用号应小于NR_syscalls),
     jae syscall_badsys         //不合法,跳入到异常处理
 syscall_call:
     call *sys_call_table(,%eax,4) //合法,对照系统调用号在系统调用表中寻找相应服务例程
     movl %eax,PT_EAX(%esp)        //保存返回值到栈中
 syscall_exit:  
     testl $_TIF_ALLWORK_MASK, %ecx   //检查是否需要处理信号
     jne syscall_exit_work        //需要,进入 syscall_exit_work
 restore_all: 
     TRACE_IRQS_IRET              //不需要,执行restore_all恢复,返回用户态
 irq_return:
     INTERRUPT_RETURN             //相当于iret

system_call流程图:

问题与分析

在MenuOS系统中使用time-asm功能时,系统会发生溢出导致崩溃

但是函数本身并没有问题,因此猜可能是在make编译的过程中出现问题,将Makefile文件中的gcc编译器改为4.8版本后问题解决。

原文地址:https://www.cnblogs.com/hzj20189205/p/9976180.html