2012-02-03 9 views
6

特定のプロセスをブロックする高レベル関数呼び出しをトレースしようとしています。そのような例はscanfです。これは '\ n'を受信するまで端末をブロックします。今度はscanfをgetcまでトレースしました(scanfはgetcを使ってstdinから文字を取得します)。私の質問は、キーボードから、カーネルを通ってgetcを返すまでのデータをどのように解釈するのか?また、scanfが端末を停止させる方法もあります(コンピュータがアイドリングしているか、別の作業をしていますか)。 ありがとうございますCブロッキングシステムコールのトレース

+3

あなたは 'strace'を指摘するように頼んでいるのですか、一般的にシステムコールをブロックする方法を尋ねていますか? – cha0site

+1

アセンブラレベルでの処理方法に興味があれば、http://www.programmersheaven.com/mb/x86_asm/295346/295346/keyboard-input/ :) – Vyktor

+2

gdbなどのデバッガで実行してみてください。 control-Cを押し、 "bt"と打ちます。 Scanfは、readを呼び出すgetcを呼び出します。これは、実際に読み取る必要があるまで返されないシステムコールです。あなたは読まれてブロックされています。 – wildplasser

答えて

5

プロセスがシステムコール(ブロッキングread(2)など)を発行するたびに、プロセスはカーネルモードで実行を開始します。つまり、特定のシステムコールを処理するカーネルコードが呼び出されます。

その後、デバイスとドライバによっては、プロセスを中断して待機キューに入れることができます。キーが押されると、割り込みを処理するカーネルコードが呼び出され、そこからどのキーが押されたかが差し引かれます。

カーネルは、この入力を待っているプロセスを再開し、カーネルアドレス空間から特定のプロセスのアドレス空間にデータをコピーしてデータを配信します。

1

システムコールにより、ユーザプログラムは事前に実行されたモードで実行されます。ユーザプログラムがシステムコールを行うと、割り込み0x80が発生します。カーネルが割り込みを受け取ると、0x80の割り込み記述子テーブル(IDT)のルックアップを行い、対応するハンドラ(syscall)を実行します。このハンドラの実行後、カーネルメモリからユーザメモリに情報をコピーした後、制御はユーザプログラムに転送されます。

この場合、scanfはライブラリ関数 "read"にマップされます。 "read"システムコールは "sys_read"を呼び出し、次にそれはgetcを使用して入力ストリームSTDINから読み込みます。お役に立てれば!

+0

必ずしもint 80hではありません。 x86は 'SYSCALL/SYSENTER'も提供しています。 –

関連する問題