[インデックス 14766] ファイルの概要
このコミットは、Go言語のビルドシステムにおいて、freebsd/arm
アーキテクチャでのCgoの利用を一時的に無効化する変更を導入しています。これは、FreeBSD-CURRENT上のARM環境でCgoを有効にしたバイナリがセグメンテーション違反(segfault)を起こす問題への対処として行われました。この変更により、Goダッシュボード上でfreebsd/arm
のビルドが安定して実行できるようになります。
コミット
commit 52dc13b5f3d9b9cbe26512fc4986372a6e97e96c
Author: Dave Cheney <dave@cheney.net>
Date: Tue Jan 1 21:46:18 2013 +1100
go/build: disable cgo on freebsd/arm
Under FreeBSD-CURRENT on arm, cgo enabled binaries segfault. Disable cgo support for the moment so we can have a freebsd/arm builder on the dashboard.
R=minux.ma, rsc, iant
CC=golang-dev
https://golang.org/cl/7031044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/52dc13b5f3d9b9cbe26512fc4986372a6e97e96c
元コミット内容
Go言語のビルドシステムにおいて、freebsd/arm
ターゲットでのCgoのサポートを無効化します。FreeBSD-CURRENT上のARM環境でCgoを有効にしたバイナリがセグメンテーション違反を起こすため、Goダッシュボードでfreebsd/arm
のビルドを可能にするための一時的な措置です。
変更の背景
この変更の背景には、特定の環境におけるGo言語のバイナリの安定性の問題があります。具体的には、FreeBSD-CURRENTオペレーティングシステム上でARMアーキテクチャをターゲットにしたGoプログラムにおいて、Cgo(C言語との連携機能)を有効にしてビルドされたバイナリが実行時にセグメンテーション違反(segfault)を起こすという深刻なバグが存在していました。
セグメンテーション違反は、プログラムがアクセスを許可されていないメモリ領域にアクセスしようとした際に発生するエラーであり、通常はプログラムのクラッシュを引き起こします。この問題は、Go言語のビルドシステムがfreebsd/arm
環境でCgoを有効にしている限り、安定したビルドとテストの実行を妨げていました。
Goプロジェクトでは、様々なプラットフォームとアーキテクチャでのビルドとテストの状況を監視するための「Goダッシュボード」を運用しています。このダッシュボード上でfreebsd/arm
のビルドが常に失敗する状態では、そのプラットフォームのサポート状況を正確に把握することが困難になります。
したがって、このコミットは、根本的なCgoの問題が解決されるまでの間、一時的な回避策としてfreebsd/arm
でのCgoを無効にすることで、ダッシュボード上でのビルドの成功を確保し、当該プラットフォームの健全性を監視できるようにすることを目的としています。これにより、開発者は他の問題に集中し、将来的にCgoの問題が解決された際に再度有効化することを視野に入れています。
前提知識の解説
Go言語 (Golang)
GoはGoogleによって開発されたオープンソースのプログラミング言語です。静的型付け、コンパイル型言語でありながら、動的型付け言語のような簡潔さと生産性を提供することを目指しています。並行処理を言語レベルでサポートするgoroutine
やchannel
といった特徴を持ち、システムプログラミング、ネットワークサービス、Webアプリケーション開発などで広く利用されています。
Cgo
Cgoは、GoプログラムからC言語のコードを呼び出したり、C言語のプログラムからGoの関数を呼び出したりするためのGo言語の機能です。これにより、既存のCライブラリをGoプロジェクトで再利用したり、パフォーマンスが重要な部分をCで記述したりすることが可能になります。Cgoを使用するには、Goのビルドプロセス中にCコンパイラ(通常はGCCやClang)が必要となります。Cgoを有効にしてビルドされたGoバイナリは、Cランタイムライブラリに依存することになります。
FreeBSD
FreeBSDは、UNIX系のオープンソースオペレーティングシステムです。高性能、安定性、セキュリティに優れており、サーバー、組み込みシステム、デスクトップなど幅広い用途で利用されています。Linuxと同様に、様々なハードウェアアーキテクチャをサポートしています。
ARMアーキテクチャ
ARM(Advanced RISC Machine)は、モバイルデバイス、組み込みシステム、IoTデバイスなどで広く使用されているCPUアーキテクチャです。低消費電力と高い性能効率が特徴で、近年ではサーバーやデスクトップPCにも採用が拡大しています。freebsd/arm
は、FreeBSDオペレーティングシステムがARMプロセッサ上で動作する環境を指します。
セグメンテーション違反 (Segmentation Fault / segfault)
セグメンテーション違反は、プログラムがアクセスを許可されていないメモリ領域にアクセスしようとした際に、オペレーティングシステムによって検出されるエラーです。これは通常、無効なポインタの逆参照、配列の範囲外アクセス、または解放済みメモリへのアクセスなど、プログラミング上のバグによって引き起こされます。セグメンテーション違反が発生すると、オペレーティングシステムは通常、そのプログラムを強制終了させます。
go/build
パッケージ
Go言語の標準ライブラリに含まれるgo/build
パッケージは、Goソースコードのパッケージ構造を解析し、ビルド制約(build tags)を評価するための機能を提供します。Goツールチェーン(go build
, go install
など)は、このパッケージを利用して、どのファイルが特定の環境(OS、アーキテクチャ、ビルドタグなど)でビルドされるべきかを決定します。cgoEnabled
のようなマップは、このパッケージ内で特定のOS/アーキテクチャの組み合わせでCgoが有効であるかどうかを管理するために使用されます。
技術的詳細
このコミットは、Go言語のビルドプロセスにおけるCgoの有効/無効を制御するメカニズムに直接介入しています。Goのsrc/pkg/go/build/build.go
ファイルには、cgoEnabled
というグローバルマップが定義されており、これは特定のオペレーティングシステムとアーキテクチャの組み合わせ(例: linux/amd64
, darwin/amd64
など)に対してCgoがデフォルトで有効であるか(true
)無効であるか(false
)を示します。
このコミットでは、cgoEnabled
マップから"freebsd/arm": true,
というエントリを削除しています。このエントリの削除は、Goのビルドツールがfreebsd/arm
環境でGoプログラムをコンパイルする際に、Cgoをデフォルトで無効にするように指示することを意味します。
具体的には、go build
コマンドがfreebsd/arm
をターゲットとして実行される際、go/build
パッケージはこのcgoEnabled
マップを参照します。"freebsd/arm"
キーがマップに存在しない、またはfalse
に設定されている場合、GoツールチェーンはCgoを必要とするソースファイル(例: import "C"
を含むファイル)をコンパイル対象から除外します。これにより、Cgoに起因するセグメンテーション違反の問題を回避できます。
この変更は、freebsd/arm
環境でのCgoの利用を完全に禁止するものではなく、あくまでデフォルトで無効にするものです。ユーザーは、環境変数CGO_ENABLED=1
を設定することで、明示的にCgoを有効にしてビルドを試みることは可能です。しかし、このコミットの目的は、Goダッシュボードのような自動ビルドシステムにおいて、問題のある環境でのCgoによるクラッシュを防ぎ、安定したビルド結果を得ることにあります。
このアプローチは、問題の根本原因(FreeBSD-CURRENT上のARMにおけるCgoのバグ)を修正するものではありませんが、その問題が解決されるまでの間、Goプロジェクト全体の健全性を維持するための実用的な回避策となります。
コアとなるコードの変更箇所
--- a/src/pkg/go/build/build.go
+++ b/src/pkg/go/build/build.go
@@ -216,7 +216,6 @@ var cgoEnabled = map[string]bool{\n \"darwin/amd64\": true,\n \"freebsd/386\": true,\n \"freebsd/amd64\": true,\n-\t\"freebsd/arm\": true,\n \"linux/386\": true,\n \"linux/amd64\": true,\n \"linux/arm\": true,\
コアとなるコードの解説
変更はsrc/pkg/go/build/build.go
ファイル内のcgoEnabled
というmap[string]bool
型の変数に対して行われています。このマップは、Goのビルドシステムが特定のオペレーティングシステムとアーキテクチャの組み合わせ(例: "os/arch"
)に対してCgoをデフォルトで有効にするかどうかを決定するために使用されます。
変更前は、以下の行が存在していました。
"freebsd/arm": true,
これは、freebsd/arm
というターゲット環境において、Cgoがデフォルトで有効であることを示していました。
このコミットでは、上記の行が削除されています。
-\t"freebsd/arm": true,\
この1行の削除により、cgoEnabled
マップから"freebsd/arm"
のエントリがなくなります。Goのビルドツールがこのマップを参照する際、"freebsd/arm"
に対応するエントリが見つからない場合、Cgoはデフォルトで無効と判断されます。結果として、freebsd/arm
環境でGoプログラムをビルドする際に、Cgoに依存するコードはコンパイルされなくなり、セグメンテーション違反の問題が回避されます。
この変更は、Goのビルドシステムが特定の環境でのCgoの挙動を制御するための、非常に直接的かつ効果的な方法です。
関連リンク
- Go CL 7031044: https://golang.org/cl/7031044
参考にした情報源リンク
- Go言語公式ドキュメント: https://go.dev/
- Cgoに関するGo公式ドキュメント: https://go.dev/blog/c-go-cgo
- FreeBSD公式ウェブサイト: https://www.freebsd.org/
- ARMアーキテクチャに関する情報 (Wikipediaなど): https://ja.wikipedia.org/wiki/ARM%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3
- セグメンテーション違反に関する情報 (Wikipediaなど): https://ja.wikipedia.org/wiki/%E3%82%BB%E3%82%B0%E3%83%A1%E3%83%B3%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%95%E3%82%A9%E3%83%BC%E3%83%AB%E3%83%88
- Goダッシュボード: https://build.go.dev/
- Goソースコード (GitHub): https://github.com/golang/go
go/build
パッケージのドキュメント: https://pkg.go.dev/go/build