検索

アクセス数
最近のコメント
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
はじめ - ノース
はじめ - ノース
はじめ - 楽打連動ユーザー
Adsense
広告情報が設定されていません。

writeのstraceのサンプル


[root@north console]# cat fdwrite.c
#include <stdio.h>
#include <fcntl.h>
#include <string.h>

char   *buff  = "abcde\n";
int    fd, cnt;

void    main(int argc, char *argv[])
{
	cnt = strlen(buff);

	if (!strcmp(argv[1], "printf")) {
		printf("%s", buff);
	}
	else {
		if (!strcmp(argv[1], "console")) {
			fd = 1;
		}
		if (!strcmp(argv[1], "file")) {
			fd = open("./file.txt", O_CREAT|O_RDWR, 0);
		}        
		__asm__("movl $4,    %eax;"
			  "movl fd,    %ebx;"
			  "movl buff,  %ecx;"
			  "movl cnt,   %edx;"
			  "int $0x80;");
	}
}

[root@north console]# ./fdwrite.out printf
abcde

[root@north console]# ./fdwrite.out console
abcde

[root@north console]# ./fdwrite.out file
[root@north console]# cat file.txt
abcde

[root@north console]# strace ./fdwrite.out printf 2>&1 | grep -A 1 abcd
write(1, "abcde\n", 6abcde
)                  = 6

[root@north console]# strace ./fdwrite.out console 2>&1 | grep -A 1 abcd
write(1, "abcde\n", 6abcde
)                  = 6

[root@north console]# strace ./fdwrite.out file 2>&1 | grep abcd
write(3, "abcde\n", 6)                  = 6


ファイル file_operationsの.writeのキャッシュ書込み後、書込み位置を値引数とする.aio_writeでキャッシュをデバイスに書込む。
       .write    :do_sync_write         (struct file *filp, const char __user *buf,size_t len,   loff_t *ppos)
       .aio_write:generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos)

コンソール file_operationsのデバイス書込み.aio_writeは実装せず、書込み位置引数をアドレスとする.writeでデバイスのコンソールに書込む。
       .write    :redirected_tty_write  (struct file *file, const char __user *buf,size_t count, loff_t *ppos)

const struct file_operations ext3_file_operations = {
       .llseek         = generic_file_llseek,
       .read           = do_sync_read,
       .write          = do_sync_write,                  <- 引数バッファをキャッシュに書込み、.aio_writeをコールする
       .aio_read       = generic_file_aio_read,
       .aio_write      = generic_file_aio_write,         <- キャッシュバッファをファイルデバイスに書込む
       .unlocked_ioctl = ext3_ioctl,
       .mmap           = generic_file_mmap,
       .open           = dquot_file_open,
       .release        = ext3_release_file,
       .fsync          = ext3_sync_file,
       .splice_read    = generic_file_splice_read,
       .splice_write   = generic_file_splice_write,
};

static const struct file_operations console_fops = {
       .llseek         = no_llseek,
       .read           = tty_read,
       .write          = redirected_tty_write,             <- 引数バッファをデバイスのコンソールに書込む
       .poll           = tty_poll,
       .unlocked_ioctl = tty_ioctl,
       .compat_ioctl   = tty_compat_ioctl,
       .open           = tty_open,
       .release        = tty_release,
       .fasync         = tty_fasync,
};
file_operationsのwriteシステムコールは、int $0x80のENTRY(system_call)から、eaxをシステムコールインデックスとするwriteシステムコールがコールされ、そこからebxのファイルIDのfile_operationsがコールされる。straceコマンドは、ptraceシステムコールのint $0x80のENTRY(system_call)下のレジスタ取得で、file_operations下の実装でなく、故にstraceコマンドのコンソールの書込み数+書込み文字の表示は、straceコマンドのptraceシステムコールで取得したENTRY(system_call)下のレジスタのfile_operationsのredirected_tty_write考慮した実装のENTRY(system_call)下の馬馬鹿鹿の実装でない。

備考

intはコードセグメントに係るipアドレス実行で、アプリケーションからコードセグメントが異るカーネルのシステムコールの呼び出しは、int $0x80で、カーネルコードセグメントのENTRY(system_call)がコールされ、eaxをインデックスとする配列のシステムコールアドレスがコールされる。

最終更新 2018/08/24 15:43:44 - north
(2018/08/24 15:34:20 作成)