writeのstraceのサンプル
[root@north console]# cat fdwrite.c
[root@north console]# ./fdwrite.out printf
[root@north console]# ./fdwrite.out console
[root@north console]# ./fdwrite.out file
[root@north console]# cat file.txt
[root@north console]# strace ./fdwrite.out printf 2>&1 | grep -A 1 abcd
[root@north console]# strace ./fdwrite.out console 2>&1 | grep -A 1 abcd
[root@north console]# strace ./fdwrite.out file 2>&1 | grep abcd
ファイル file_operationsの.writeのキャッシュ書込み後、書込み位置を値引数とする.aio_writeでキャッシュをデバイスに書込む。
コンソール file_operationsのデバイス書込み.aio_writeは実装せず、書込み位置引数をアドレスとする.writeでデバイスのコンソールに書込む。
#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)下の馬馬鹿鹿の実装でない。