Pro Yearly is on sale from $80 to $50! »

Linux の Debug 機能

Linux の Debug 機能

457c3c757b4fae74c7cdc79ad67a5645?s=128

Masami Ichikawa

May 18, 2016
Tweet

Transcript

  1. Linux の Debug 機能 • @masami256

  2. Overview • Linux の Debug 機能を紹介します • Debug と言っても gdb

    でデバッグという感じで はありません • 実行中のカーネルの情報を見るのに適した機 能です • スクリプト言語で処理を書けるものもあります
  3. Importance • debug 系のパッケージがあると捗ります • -debuginfo • RHEL 系 •

    -dbgsym • Ubuntu • symbol 見れないのはやっぱり辛い>< • debug 系のパッケージを提供していないディストリビューション の場合は自前でビルドしましょう
  4. Tools • SystemTap • Perf • Ftrace • eBPF

  5. SystemTap • 専用のスクリプト言語がある • c 言語の関数も組み込める • テトリスを書ける ( ´∀

    ` )b グッ !
  6. Perf • 性能解析計測ツール • プロセスのボトルネック部分調査 • システム全体で遅い部分の調査 • キャッシュミス等の調査

  7. Ftrace • Linux カーネルの関数のトレース • 関数のコールフローだけでなく、処理時間も計 測できる • 素の ftrace

    を使うよりは trace-cmd とかを 使うほうが楽
  8. eBPF • BSD Packet Filter • カーネルに JIT コンパイラがあり、フィルタを JIT

    コンパイル • パケットフィルタとは思えない高機能さ • ループ処理は v4.5 時点では書けなかったはず • 素の eBPF を使う場合は c 言語でプログラミング • 新しいカーネルを使うほうが良い • 便利機能が追加されるし
  9. Useful tools • perf-tools • https://github.com/brendangregg/perf-tools • ftrace ベースのスクリプト集 •

    bcc • https://github.com/iovisor/bcc • Python でスクリプトを書いて eBPF を使える • Python スクリプト内に c 言語の関数を組み込める
  10. Example:Perf

  11. Example:Perf Cont’d

  12. Example:Perf Cont’d

  13. Example:Perf Cont’d

  14. Example:bcc bcc 付属の tcp connection のモニタリングスクリプトを実行 http status 302 が最初に返

    り、 Location ヘッダにある先に接続 するので 2 回分のログが出てる http status 302 が最初に返 り、 Location ヘッダにある先に接続 するので 2 回分のログが出てる
  15. Example:systemtap #!/usr/bin/env stap global call_count = 0 probe process("/usr/lib/libruby.so.2.3.0").function("vm_exec_core") {

    call_count += 1 } probe begin { printf("waiting...\n") } probe end { printf("vm_exec_core() was called %d times\n", call_count) } シンボル情報を strip していないバイナリ シンボル情報を strip していないバイナリ
  16. Example:systemtap Cont’d %{ #include <linux/sched.h> #include <linux/thread_info.h> #include <linux/pid_namespace.h> %}

    function show_pidtree:long(pn:long) %{ struct task_struct *task; int pid_nr = STAP_ARG_pn; struct pid_namespace *pid_ns; int indent_level = 0, i; struct pid *pid = find_get_pid(pid_nr); if (!pid) { STAP_PRINTF("Could not find pid %d\n", pid_nr); STAP_RETURN(-1); } task = pid_task(pid, PIDTYPE_PID); if (!task) { STAP_PRINTF("Cannot find task by pid %d\n", pid_nr); STAP_RETURN(-1); } pid_ns = task->nsproxy->pid_ns_for_children; do { pid_nr = __task_pid_nr_ns(task, PIDTYPE_PID, pid_ns); for (i = 0; i < indent_level; i++) STAP_PRINTF(" "); STAP_PRINTF("pid %d\n", pid_nr); pid_ns = pid_ns->parent; indent_level++; } while (pid_ns); STAP_RETURN(0); %} c 言語による処理の記述 STAP_XXX は systemtap 固有の書き方
  17. Example:systemtap Cont’d プロセスが所属する全 PID 名前空間での PID を取得 コンテナ内の pid1 はホスト環境の

    pid だと 5145 コンテナ内の pid1 はホスト環境の pid だと 5145
  18. Example:ftrace(perf- tools) masami@arch perf-tools[master]$ sudo ./syscount -c ~/login.rb Tracing while

    running: "/home/masami/login.rb"... SYSCALL COUNT clock_gettime 1 exit_group 1 set_tid_address 1 sysinfo 1 access 2 connect 2 getrandom 2 getsockname 2 madvise 2 pipe2 2 poll 2 setsockopt 2 socket 2 exit 3 getrlimit 3 rt_sigprocmask 3 sched_getaffinity 3 sigaltstack 3 set_robust_list 4 prctl 5 ppoll 6 lseek 7 munmap 7 getdents 8 write 10 futex 14 rt_sigaction 21 newstat 42 mprotect 62 getgid 79 getegid 80 geteuid 80 getuid 80 mmap 83 fcntl 93 brk 102 ioctl 110 close 253 newfstat 310 read 379 newlstat 553 open 984
  19. Summary • カーネル、周辺ツールともに日々進化してます • 新し目のカーネルが必要になるけど・・・ • systemtap ならユーザーランドのコードも対応 可能 •

    Happy Debugging ヽ (=´▽`=) ノ
  20. Reference • http://www.brendangregg.com/ • http://kernhack.hatenablog.com/