0

次のようにランタイムパッケージを使用する単純な go コードがあります。

package main

import (
    "runtime"
    "fmt"
)

func bar() {
    pc := make([]uintptr, 1000)
    n := runtime.Callers(0, pc)
    frames := runtime.CallersFrames(pc[:n])
    for {
        frame, more := frames.Next()
        if ! more {
            break
        }
        fmt.Printf("FILE = %s and FUNC = %s\n", frame.File, frame.Function)
    }
}

func foo() {
    bar()
}

func main() {
    foo()
}

Ubuntu マシン (マシン Aなど)のカスタムの場所 (/home/ userA /bin/go) にGo バイナリをインストールしました。

マシンAでコンパイルし、同じマシンで実行可能ファイルを実行して出力を取得しました。

FILE = /home/userA/bin/go/src/runtime/extern.go and FUNC = runtime.Callers
FILE = /home/userA/src/main.go and FUNC = main.bar
FILE = /home/userA/src/main.go and FUNC = main.foo
FILE = /home/userA/src/main.go and FUNC = main.main
FILE = /home/userA/bin/go/src/runtime/proc.go and FUNC = runtime.main

ここで、コンパイル済みの実行可能ファイルを別の Ubuntu マシン (マシン Bなど) にコピーし、そこで Go バイナリを別のカスタムの場所 (/home/ userB /bin/go) にインストールしました。/home/userBから実行可能ファイルを実行しました。しかし、今回も以前と同じ出力が得られました。

FILE = /home/userA/bin/go/src/runtime/extern.go and FUNC = runtime.Callers
FILE = /home/userA/src/main.go and FUNC = main.bar
FILE = /home/userA/src/main.go and FUNC = main.foo
FILE = /home/userA/src/main.go and FUNC = main.main
FILE = /home/userA/bin/go/src/runtime/proc.go and FUNC = runtime.main

コンパイル時にランタイムパッケージがスタック フレームを設定しているようです。

マシンAでは/home/userAとして、マシンBでは /home/ userBとして設定したGOPATH環境変数に基づいて、ファイル パスに対して何らかの処理を行う必要があります。

これらの各ファイル パスから GOPATH 部分を削除する必要があります。私はこの単純な関数呼び出しでそれをやっています:strings.Replace(frame.File, GOPATH, "", 1)

ただし、ランタイム パッケージのこの動作のため、関数はマシンBstrings.Replaceのファイル パスの最初の部分を置き換えることができません。

マシンBでこれを達成する方法についてのアイデアはありますか?

アップデート

@JimB からの提案に従って、プロジェクトをビルドしました

CGO_ENABLED=0 go build -a -ldflags="-w -s" -gcflags=-trimpath=/home/userA -asmflags=-trimpath=/home/userA

ここで、同じマシンで実行可能ファイルを実行すると、次のような出力が得られます。

FILE = /home/userA/bin/go/src/runtime/extern.go and FUNC = runtime.Callers
FILE = /home/userA/src/vendor/github.com/kataras/golog/golog.go and FUNC = vendor/github.com/kataras/golog.Error
FILE = /home/userA/src/test/test_logger.go and FUNC = test/test_logger.TestLogger
FILE = src/main.go and FUNC = main.bar
FILE = src/main.go and FUNC = main.foo
FILE = src/main.go and FUNC = main.main
FILE = /home/userA/bin/go/src/runtime/proc.go and FUNC = runtime.main

パス プレフィックスは、メイン ファイルに対してのみトリミングされます。ベンダーがインポートしたパッケージまたはローカルにインポートしたパッケージにはまだあります。

4

1 に答える 1