概要
以下、自分用のメモです。特にGo限定の話では無くて、straceコマンドのメモです。
たまに、プログラムが内部で読んでいるシステムコールが見たいときがあったりします。
Linuxの場合は、strace コマンドで、macの場合は確かdtrussだったはず。Windowsの場合は sysinternal のProcess Explorerですね。
macの場合はSIPを止めないといけないので、若干面倒。
以下、Goのプログラムを実行してstraceコマンドでシステムコールの呼び出しを出力してみるサンプルです。
サンプル
コードは以下のようなものです。なんでも良いのですが、一応ファイルの入出力をしています。
package main import ( "fmt" "os" ) func main() { file, err := os.Create("out.txt") if err != nil { panic(err) } defer file.Close() ch := make(chan int) go func() { defer close(ch) for _, v := range []int{1, 2, 3, 4, 5} { ch <- v } }() for v := range ch { fmt.Fprintln(file, v) } }
実行するためのタスクファイルは以下です。
version: '3' vars: APPNAME: ./app SYSCALLLOG: syscall.log COMMANDOUT: out.txt STRACEFILTER: openat,read,write,clone,close tasks: run: cmds: - go build -o {{ .APPNAME }} - strace -y -f -e {{ .STRACEFILTER }} {{ .APPNAME }} 2>&1 1>/dev/null | tee {{ .SYSCALLLOG }} clean: cmds: - rm -f {{ .APPNAME }} {{ .COMMANDOUT }} {{ .SYSCALLLOG }}
実行すると以下のようになります。
$ task run task: [run] go build -o ./app task: [run] strace -y -f -e openat,read,write,clone,close ./app 2>&1 1>/dev/null | tee syscall.log openat(AT_FDCWD, "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", O_RDONLY) = 3</sys/kernel/mm/transparent_hugepage/hpage_pmd_size> read(3</sys/kernel/mm/transparent_hugepage/hpage_pmd_size>, "2097152\n", 20) = 8 close(3</sys/kernel/mm/transparent_hugepage/hpage_pmd_size>) = 0 clone(child_stack=0xc000074000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLSstrace: Process 3677 attached , tls=0xc000064090) = 3677 [pid 3676] clone(child_stack=0xc000076000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLSstrace: Process 3678 attached , tls=0xc000064490) = 3678 [pid 3676] clone(child_stack=0xc000070000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLSstrace: Process 3679 attached , tls=0xc000064890) = 3679 [pid 3678] clone(child_stack=0xc000112000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLSstrace: Process 3680 attached , tls=0xc000100090) = 3680 [pid 3676] clone(child_stack=0xc000072000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLSstrace: Process 3681 attached , tls=0xc000064c90) = 3681 [pid 3676] openat(AT_FDCWD, "out.txt", O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 3</workspace/go-syscall-with-strace/out.txt> [pid 3676] write(3</workspace/go-syscall-with-strace/out.txt>, "1\n", 2) = 2 [pid 3676] write(3</workspace/go-syscall-with-strace/out.txt>, "2\n", 2) = 2 [pid 3681] write(3</workspace/go-syscall-with-strace/out.txt>, "3\n", 2) = 2 [pid 3681] write(3</workspace/go-syscall-with-strace/out.txt>, "4\n", 2) = 2 [pid 3681] write(3</workspace/go-syscall-with-strace/out.txt>, "5\n", 2) = 2 [pid 3676] close(3</workspace/go-syscall-with-strace/out.txt>) = 0 [pid 3681] +++ exited with 0 +++ [pid 3680] +++ exited with 0 +++ [pid 3679] +++ exited with 0 +++ [pid 3678] +++ exited with 0 +++ [pid 3677] +++ exited with 0 +++ +++ exited with 0 +++
cloneとなっているのは、スレッドが起動している部分ですね。
参考情報
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。