Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
入門 "Hello World"
Search
srup
November 13, 2019
Technology
0
100
入門 "Hello World"
Recruit Technology Internship LT
srup
November 13, 2019
Tweet
Share
More Decks by srup
See All by srup
Spectre-Variant1_Internals.pdf
mmxsrup
0
71
Context-Sensitive Fencing
mmxsrup
1
70
DBI (Dynamic Binary Instrumentation)
mmxsrup
0
19
Other Decks in Technology
See All in Technology
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
6
55k
20250122_FinJAWS
takuyay0ne
2
110
「人物ごとのアルバム」の精度改善の軌跡/Improving accuracy of albums by person
mixi_engineers
PRO
1
140
comilioとCloudflare、そして未来へと向けて
oliver_diary
6
460
カップ麺の待ち時間(3分)でわかるPartyRockアップデート
ryutakondo
0
150
Oracle Exadata Database Service(Dedicated Infrastructure):サービス概要のご紹介
oracle4engineer
PRO
0
12k
2024年活動報告会(人材育成推進WG・ビジネスサブWG) / 20250114-OIDF-J-EduWG-BizSWG
oidfj
0
260
月間60万ユーザーを抱える 個人開発サービス「Walica」の 技術スタック変遷
miyachin
1
160
Reactフレームワークプロダクトを モバイルアプリにして、もっと便利に。 ユーザに価値を届けよう。/React Framework with Capacitor
rdlabo
0
140
TSのコードをRustで書き直した話
askua
3
370
いま現場PMのあなたが、 経営と向き合うPMになるために 必要なこと、腹をくくること
hiro93n
9
8k
iPadOS18でフローティングタブバーを解除してみた
sansantech
PRO
1
150
Featured
See All Featured
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
19
2.4k
Designing Experiences People Love
moore
139
23k
Learning to Love Humans: Emotional Interface Design
aarron
274
40k
Rails Girls Zürich Keynote
gr2m
94
13k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
174
51k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.4k
A designer walks into a library…
pauljervisheath
205
24k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.5k
Practical Orchestrator
shlominoach
186
10k
Product Roadmaps are Hard
iamctodd
PRO
50
11k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
49
2.2k
Designing for humans not robots
tammielis
250
25k
Transcript
入門 “Hello World” @mmxsrup
“Hello World” 完全に理解した ! と、ツイートしてしまうと ... 2
問: 以下のプログラムについて説明せよ (10点) #include <stdio.h> int main(void) { printf("Hello World\n");
return 0; } print("Hello World") C Python 3 と、リプが飛んできます
問: 以下のプログラムについて説明せよ (10点) #include <stdio.h> int main(void) { printf("Hello World\n");
return 0; } print("Hello World") C Python “Hello World” が表示されます !! 4
問: 以下のプログラムについて説明せよ (10点) #include <stdio.h> int main(void) { printf("Hello World\n");
return 0; } print("Hello World") C Python “Hello World” が表示されます !! 人権無いですよ。 5
“Hello World” の全体像 6
int main(void) { printf("Hello World\n"); return 0; } Hello World
ソースコード オブジェクト ファイル 実行ファイル スクリーン OS プログラム実行 ランタイム ライブラリ コンパイラ リンカ ローダ printf() 呼び出し システム コール ドライバ カーネル 空間 ユーザ 空間 7
ユーザ空間での話 8
int main(void) { printf("Hello World\n"); return 0; } Hello World
ソースコード オブジェクト ファイル 実行ファイル スクリーン OS プログラム実行 ランタイム ライブラリ コンパイラ リンカ ローダ printf() 呼び出し システム コール ドライバ カーネル 空間 ユーザ 空間 9
ソースコードから機械語へ # gcc -v hello.c # file ./a.out hello.o: ELF
64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped # xxd ./a.out 00000000: 7F45 4C46 0201 0100 0000 0000 0000 0000 .ELF............ 00000010: 0300 3E00 0100 0000 3005 0000 0000 0000 ..>.....0....... .. 000006d0: F3C3 0000 4883 EC08 4883 C408 C300 0000 ....H...H....... 000006e0: 0100 0200 4865 6C6C 6F20 576F 726C 6400 ....Hello World. -v でコンパイル処理の各段階が見れる 生成された実行ファイル(a.out)の形式を調べる 実行ファイルの内容を16進数で出力する 10 #include <stdio.h> int main(void) { printf("Hello World\n"); return 0; } hello.c
ソースコードから機械語へ #objdump -d ./a.out 000000000000063a <main>: 63a: 55 push %rbp
63b: 48 89 e5 mov %rsp,%rbp 63e: 48 8d 3d 9f 00 00 00 lea 0x9f(%rip),%rdi #<_IO_stdin_used+0x4> 645: e8 c6 fe ff ff callq 510 <puts@plt> 64a: b8 00 00 00 00 mov $0x0,%eax 64f: 5d pop %rbp 650: c3 retq 機械語 アセンブリ言語 ※ gcc -fno-builtin-printf で最適化を抑止可 11 機械語命令に対応するアセンブラを表示する 最適化で printf() → puts() puts()関数を 呼び出している (callq)
ソースコードから機械語へ # nm ./a.out 0000000000200dc8 d _DYNAMIC 0000000000200fb8 d _GLOBAL_OFFSET_TABLE_
.. 000000000000063a T main U puts@@GLIBC_2.2.5 # ldd ./a.out linux-vdso.so.1 (0x00007ffcb177c000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f68b7887000) /lib64/ld-linux-x86-64.so.2 (0x00007f68b7e7a000) 12 オブジェクトファイルのシンボルリストを表示する puts() 関数のコードは a.out には存在していない ? 使用する共有ライブラリを表示する libcの中に puts() 関数がある
int main(void) { printf("Hello World\n"); return 0; } Hello World
ソースコード オブジェクト ファイル 実行ファイル スクリーン OS プログラム実行 ランタイム ライブラリ コンパイラ リンカ ローダ printf() 呼び出し システム コール ドライバ カーネル 空間 ユーザ 空間 13 ユーザー空間のプログラムが OSの機能 を呼び出すために使用する機構
プログラムの実行中に呼び出されるシステムコール # strace ./a.out execve("./a.out", ["./a.out"], 0x7ffd98c59750 /* 74 vars
*/) = 0 brk(NULL) = 0x562d596e7000 ... fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0 brk(NULL) = 0x562d596e7000 brk(0x562d59708000) = 0x562d59708000 write(1, "Hello World\n", 12Hello World ) = 12 14 最後に write システムコール が呼び出されている ! 実行中に呼び出されるシステムコールを表示 プログラムのロード
puts() 関数から write システムコールへ # gdb ./a.out (gdb) catch syscall
write (gdb) run (gdb) backtrace #0 0x00007ffff7af4154 in __GI___libc_write #1 0x00007ffff7a6f1bd in _IO_new_file_write #2 0x00007ffff7a70f51 in new_do_write #3 _IO_new_do_write #4 0x00007ffff7a71403 in _IO_new_file_overflow #5 0x00007ffff7a64b62 in _IO_puts (str=0x5555555546e4 "Hello World") #6 0x000055555555464a in main () 15 write システムコール呼び出し時にブレークを設定 write システムコールまでの過程を表示 puts() 関数から writeシステムコール まで多くの関数を経由している
ユーザ空間での “Hello World” のまとめ libc 関数の呼び出し (puts(), printf(), … )
ユーザープログラム (a.out) システムコール (write, read, ioctl, ..) #include <stdio.h> int main(void) { printf("Hello World\n"); return 0; } char *hello = "Hello World\n"; int main() { asm volatile ( "mov $1, %rax\n" // sys num "mov $0, %rdi\n" // fd "mov hello,%rsi\n" // buf addr "mov $13, %rdx\n" // size "syscall\n ); } 16 直接 システムコール を叩く libc_write(), new_file_write(), .. callq puts x64 環境のみ
カーネル空間での話 17
int main(void) { printf("Hello World\n"); return 0; } Hello World
ソースコード オブジェクト ファイル 実行ファイル スクリーン OS プログラム実行 ランタイム ライブラリ コンパイラ リンカ ローダ printf() 呼び出し システム コール ドライバ カーネル 空間 ユーザ 空間 18
Kernel 内の関数をトレース (a.out) # cd /sys/kernel/debug/tracing # echo 1 >
tracing_on; taskset -c 2 ./a.out ; echo 0 > tracing_on; # cat per_cpu/cpu2/trace 2) | SyS_write() { 2) | vfs_write() { 2) | __vfs_write() { 2) | tty_write() { 2) | n_tty_write() { 2) | pty_write() { 2) | tty_flip_buffer_push() { 2) + 16.901 us | } /* pty_write */ buffer (Line discipline) に書き込む 19 ftraceを用いて Kernel内の関数呼び出しをトレース pty: 擬似端末 ハードウェアなどを使用しない テキスト端末のインターフェイス
Kernel 内の関数をトレース (gnome-terminal) # echo (gnome-terminal-server-pid) > set_ftrace_pid # echo
1 > tracing_on; taskset -c 2 ./a.out ; echo 0 > tracing_on; # cat trace 3) | SyS_read() { 3) | vfs_read() { 3) | __vfs_read() { 3) | tty_read() { 3) | n_tty_read() { 3) 0.206 us | copy_from_read_buf(); 3) + 11.515 us | } tty queue からデータを コピーしている. 20
Kernel 内の関数をトレース (Xorg) # echo (Xorg-pid) > set_ftrace_pid # echo
1 > tracing_on; taskset -c 2 ./a.out ; echo 0 > tracing_on; # cat trace 3) | SyS_ioctl() { 3) | do_vfs_ioctl() { 3) | drm_ioctl [drm]() { 3) | drm_ioctl_kernel [drm]() { ... 3) | __i915_gem_object_flush_for_display [i915]() { 3) 0.611 us | flush_write_domain [i915](); 3) 1.732 us | } 21 ioctl システムコールから drm (Direct Rendering Manager) を通して、 i915 (intelのgpuドライバー) を叩く 簡単に操作可能なGUI環境をユーザーに 提供してくれる、X Window server
カーネル空間での “Hello World” のまとめ a.out 22 write システムコール pty slave
pty master line discipline gnome- terminal X-Server (Xorg) Hello World DRM GPU driver ioctl システムコール pty_write tty_read プロセス間通信など ? フレームバッファに 書き込み 擬似端末
難しすぎる... (よくわからん...) 23
問: 以下のプログラムについて説明せよ (10点) #include <stdio.h> int main(void) { printf("Hello World\n");
return 0; } print("Hello World") C Python ここに記すには 余白が狭すぎる。 24
ご清聴ありがとうございました 25
実行環境 # uname -a Linux srupX1 4.15.0-65-generic #74-Ubuntu SMP Tue
Sep 17 17:06:04 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux # gcc --version gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0 # ldd --version ldd (Ubuntu GLIBC 2.27-3ubuntu1) 2.27 26
参考資料 • Tearing apart printf() (https://www.maizure.org/projects/printf/ ) • Ftraceでカーネルの一部の処理を追いかける方法 (https://qiita.com/mhiramat/items/42a6af4f3c289ad37095
) 27