跟踪系统调用
调试MenuOS新增的函数
重新下载 menu.git
可以看到 在test.c
文件中增加了新的函数Time
和TimeAsm
:
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;
}
其调用接口分别为time
和time-asm
:
MenuConfig("time","Show System Time",Time);
MenuConfig("time-asm","Show System Time(asm)",TimeAsm);
其功能为显示当前系统时间,
make rootfs
可以打开增加了新功能的MenuOS系统,在系统中使用新增的功能time
和time-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版本后问题解决。