いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-287 (goアプリが使っているシステムコールを見てみる (strace))

概要

以下、自分用のメモです。特に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となっているのは、スレッドが起動している部分ですね。

参考情報

github.com

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。