次のようにランタイムパッケージを使用する単純な 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
パス プレフィックスは、メイン ファイルに対してのみトリミングされます。ベンダーがインポートしたパッケージまたはローカルにインポートしたパッケージにはまだあります。