Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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によって開発されたオープンソースのプログラミング言語です。静的型付け、コンパイル型言語でありながら、動的型付け言語のような簡潔さと生産性を提供することを目指しています。並行処理を言語レベルでサポートするgoroutinechannelといった特徴を持ち、システムプログラミング、ネットワークサービス、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の挙動を制御するための、非常に直接的かつ効果的な方法です。

関連リンク

参考にした情報源リンク