2012-02-03 103 views
6

我正在尝试追踪阻止特定进程的高级函数调用。这样的一个例子是scanf,它阻止终端,直到收到'\ n'。现在我将scanf追踪到getc(scanf使用getc从stdin获取字符)。我的问题是,解释来自键盘的数据,整个内核以及getc的返回所需的过程是什么?此外,scanf如何终止终端(计算机是闲置还是处理其他任务)? 谢谢追踪C阻塞系统调用

+3

您是在要求我们指出'strace',还是您要问在一般情况下如何阻止系统调用? – cha0site 2012-02-03 11:30:20

+1

如果您对如何在汇编级别上完成它感兴趣:http://www.programmersheaven.com/mb/x86_asm/295346/295346/keyboard-input/ :) – Vyktor 2012-02-03 11:31:42

+2

尝试在调试器(如gdb)下运行它。点击control-C,然后输入“bt”。 Scanf调用getc,它调用read,这是一个系统调用,只有在实际需要读取时才会返回。你在阅读中被封锁。 – wildplasser 2012-02-03 11:32:50

回答

5

只要进程发出系统调用(例如阻塞read(2)),进程就开始在内核模式下执行,即处理特定系统调用的内核代码被调用。

之后,根据基础设备和驱动程序,可以挂起进程并放入等待队列。当一个键被按下时,处理中断的内核代码被调用,并从那里扣除哪个键被按下。

内核然后恢复正在等待此输入​​的进程,并通过将内核地址空间复制到特定进程的地址空间来传递数据。

1

系统调用使用户程序能够以previliged模式执行。当用户程序进行系统调用时,它会生成中断0x80。当内核收到中断时,它将在中断描述符表(IDT)上查找0x80并执行相应的处理程序(系统调用)。执行此处理程序后,将控制信息从内核内存复制到用户内存后,将转移到用户程序。

在这种情况下,scanf被映射到库函数“read”。 “read”系统调用调用“sys_read”,然后使用getc从输入流STDIN中读取数据。希望这可以帮助!

+0

它不一定是'int 80h'。 x86也提供了'SYSCALL/SYSENTER'。 – 2012-02-03 14:30:47