printf
私のCコードで実行されたときにどのカーネルモジュールが呼び出されるのか知りたいです。どうやって見つけることができますか? 。ldd
私は似たようなものを探しています。基本的に学びたいです。ファイル構造printfを担当します。
次のコードを考えてみましょう
#include <stdio.h>
int main()
{
int i = 0;
int N = 100;
while (i++ <= N) {
printf("%d ", i);
}
return 0;
}
perf コマンドを実行すると、perf record -e cycles -j any -a -o perf.data ./test
データファイルに次の出力が表示されます。
# Overhead Command Source Shared Object Source Symbol Target Symbol Basic Blo
# ........ ....... .................... ...................................... ...................................... .........
#
21.19% swapper [unknown] [k] 0000000000000000 [k] 0000000000000000 -
10.98% swapper [kernel.vmlinux] [k] __intel_pmu_enable_all [k] native_write_msr -
10.66% swapper [kernel.vmlinux] [k] intel_pmu_lbr_enable_all [k] __intel_pmu_enable_all -
10.66% swapper [kernel.vmlinux] [k] native_write_msr [k] intel_pmu_lbr_enable_all -
5.00% perf [kernel.vmlinux] [k] smp_call_function_single [k] smp_call_function_single -
3.14% swapper [kernel.vmlinux] [k] acpi_os_read_memory [k] acpi_os_read_memory -
2.23% swapper [kernel.vmlinux] [k] intel_idle [k] intel_idle -
1.88% swapper [kernel.vmlinux] [k] sched_clock [k] native_sched_clock -
1.82% swapper [kernel.vmlinux] [k] native_sched_clock [k] sched_clock -
1.15% swapper [kernel.vmlinux] [k] nmi_handle [k] sched_clock -
1.15% swapper [kernel.vmlinux] [k] native_set_fixmap [k] native_set_fixmap -
1.09% swapper [kernel.vmlinux] [k] sched_clock [k] nmi_handle -
0.82% swapper [kernel.vmlinux] [k] __x86_indirect_thunk_rax [k] __x86_indirect_thunk_rax -
...
...
では、モジュール/ファイルと接続はどこにありますかprintf
?パフォーマンス出力の最初の行はどういう意味ですか?
printf
画面に何かを表示するために実行されるコードを分析したいとします。
修正する:
次の出力は、私が望むオプションを使用してソースから再コンパイルしたカスタムglibcのバージョンに対して私のテストプログラムがリンクされていることを示しています。
$ ldd test
linux-vdso.so.1 => (0x00007ffe26875000)
libc.so.6 => /opt/glibc-2.23-install/libc.so.6 (0x00007f28196d5000)
/opt/glibc-2.23-install/lib/ld-2.23.so => /lib64/ld-linux-x86-64.so.2 (0x00007f2819a76000)
ベストアンサー1
見ているイベントはtest
プログラムから得られたものではありません。 「コマンド」フィールドで行を見つけてtest
拡大する必要があります。運が良ければ(perf record
サンプルのため)、次のような項目を見ることができます。
1.31% 590585 libc-2.30.so [.] __vfprintf_internal [.] __vfprintf_internal
0.18% 590585 libc-2.30.so [.] _itoa_word [.] _itoa_word
0.18% 590585 libc-2.30.so [.] __vfprintf_internal [.] _IO_file_xsputn@@GLIBC_2.2.5
0.18% 590585 libc-2.30.so [.] _IO_file_xsputn@@GLIBC_2.2.5 [.] __vfprintf_internal
0.18% 590585 libc-2.30.so [.] __strchrnul_avx2 [.] __strchrnul_avx2
test
590585
などは(私のトレースで)呼び出しにprintf
対応するCライブラリへの呼び出しを示しています。
printf
主にCライブラリで実装されているため、カーネルには多くの依存関係が見つかりません。プログラムを実行すると、strace
次のような結果が表示されます。
...
write(1, "1 2 3 4 5 6 7 8 9 10 11 12 13 14"..., 2961 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 ) = 296
exit_group(0) = ?
+++ exited with 0 +++
プログラムで唯一の出力関連のシステムコールはシングルコールですwrite
。 Cライブラリは出力をバッファリングするため、すべての呼び出しがprintf
バッファに追加され、プログラムが終了すると、バッファは単一の呼び出しにフラッシュされます。
GNU Cライブラリでどのように実装されるかを見るには、次のprintf
ソースコードを見てください。stdio-common
printf.c
。直接分析すると、printf
より良い結果が得られますgprof
。