[インデックス 15774] ファイルの概要
このコミットは、Go言語のランタイムにおけるFreeBSD/ARMアーキテクチャ向けのシグナルハンドリングに関するビルドの問題を修正するものです。具体的には、以前のコード再編成(reorg)によって発生したビルドエラーを解消し、SIG_REGS
マクロの定義を修正し、SIG_CODE0
マクロを追加しています。
コミット
commit c89fc124c424b194af37c5ca71918f6b89a5c60e
Author: Russ Cox <rsc@golang.org>
Date: Thu Mar 14 17:50:07 2013 -0400
runtime: fix build for freebsd/arm after reorg
R=golang-dev
CC=golang-dev
https://golang.org/cl/7701046
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/c89fc124c424b194af37c5ca71918f6b89a5c60e
元コミット内容
runtime: fix build for freebsd/arm after reorg
変更の背景
このコミットは、GoランタイムのFreeBSD/ARMビルドが、以前のコード再編成("reorg")によって壊れてしまった問題を修正するために行われました。Go言語のランタイムは、異なるオペレーティングシステム(OS)やアーキテクチャ(CPU)に対応するために、OSやアーキテクチャ固有のコードを含んでいます。シグナルハンドリングは、プログラムが予期せぬイベント(例えば、不正なメモリアクセスや割り込み)に遭遇した際に、適切に処理するための重要なメカニズムです。
FreeBSD/ARM環境では、シグナルハンドリングのコンテキスト情報(レジスタの状態など)にアクセスするための特定の方法が必要です。以前のコード再編成により、このアクセス方法が変更されたか、または互換性が失われたため、ビルドエラーが発生するようになりました。このコミットは、その互換性の問題を解決し、FreeBSD/ARM環境でのGoランタイムのビルドを再び可能にすることを目的としています。
具体的には、FreeBSDのucontext_t
構造体内のuc_mcontext
フィールドへのアクセス方法が、以前のSigcontext
型へのキャストが不要になったか、あるいは不適切になった可能性があります。また、シグナル情報構造体(siginfo_t
)からシグナルコード(si_code
)を取得するための新しいマクロが必要になったことも背景にあります。
前提知識の解説
1. Goランタイム (Go Runtime)
Goランタイムは、Goプログラムの実行を管理するシステムです。これには、ガベージコレクション、スケジューリング、メモリ管理、そしてOSとのインタラクション(シグナルハンドリングを含む)などが含まれます。Goプログラムは、OSのネイティブスレッド上で動作しますが、GoランタイムがそのスレッドのスケジューリングやGoルーチンの管理を行います。
2. シグナルハンドリング (Signal Handling)
シグナルは、オペレーティングシステムがプロセスに非同期的に通知するイベントです。例えば、Ctrl+Cを押すとSIGINT
シグナルが、不正なメモリアクセスがあるとSIGSEGV
シグナルがプロセスに送信されます。プログラムはこれらのシグナルを捕捉し、特定の処理(シグナルハンドラ)を実行することができます。
3. ucontext_t
と mcontext_t
(FreeBSD)
ucontext_t
: POSIX標準で定義されている構造体で、シグナルハンドラが呼び出された時点でのプロセスの実行コンテキスト(レジスタ、シグナルマスク、スタックなど)を保存するために使用されます。これにより、シグナルハンドラから元の実行状態に復帰したり、別のコンテキストに切り替えたりすることが可能になります。mcontext_t
:ucontext_t
構造体の一部として含まれる構造体で、CPUのレジスタの状態(汎用レジスタ、プログラムカウンタ、スタックポインタなど)を保持します。アーキテクチャ(ARM、x86など)に依存するレジスタ情報が格納されます。FreeBSDでは、mcontext_t
は通常、__mcontext
という名前で定義され、その中に__gregs
(汎用レジスタ)などのフィールドが含まれます。
4. siginfo_t
(FreeBSD)
siginfo_t
構造体は、シグナルに関する追加情報を提供するものです。例えば、SIGSEGV
の場合、どのメモリアドレスでエラーが発生したか、SIGCHLD
の場合、どのプロセスが終了したかなどの情報が含まれます。si_code
フィールドは、シグナルが生成された原因を示すコードです。
5. Cプリプロセッサマクロ (#define
)
C言語のプリプロセッサマクロは、コンパイル前にテキスト置換を行う機能です。#define
ディレクティブを使って定義され、コードの可読性を高めたり、条件付きコンパイルを行ったりするために使用されます。このコミットでは、シグナルコンテキストからレジスタ情報にアクセスするためのマクロが定義されています。
6. ARMアーキテクチャ
ARM(Advanced RISC Machine)は、モバイルデバイスや組み込みシステムで広く使用されているRISC(Reduced Instruction Set Computer)ベースのCPUアーキテクチャです。レジスタの構成や命令セットがx86などとは異なります。
技術的詳細
このコミットの主要な変更点は、src/pkg/runtime/signal_freebsd_arm.h
ファイル内のSIG_REGS
マクロの定義修正と、SIG_CODE0
マクロの追加です。
SIG_REGS
マクロの修正
変更前:
#define SIG_REGS(ctxt) (((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext))
変更後:
#define SIG_REGS(ctxt) (((Ucontext*)(ctxt))->uc_mcontext)
この変更は、uc_mcontext
フィールドへのアクセス方法を修正しています。
ctxt
は、ucontext_t
型へのポインタとして扱われるべきです。したがって、まず(Ucontext*)(ctxt)
でucontext_t
型にキャストしています。((Ucontext*)(ctxt))->uc_mcontext
は、ucontext_t
構造体のuc_mcontext
フィールドにアクセスします。このフィールドは、FreeBSDのmcontext_t
型(またはそれに相当する型)です。- 変更前は、この
uc_mcontext
の結果をさらに(Sigcontext*)
にキャストしていました。これは、以前のFreeBSDのバージョンや、Goランタイムの内部的な型定義において、uc_mcontext
が直接Sigcontext
型として扱われることを期待していたか、あるいは互換性のためにそのようなキャストが必要だったことを示唆しています。 - しかし、"reorg"(コード再編成)によって、
uc_mcontext
の型が変更されたか、またはSigcontext
へのキャストが不要になった、あるいは不適切になったと考えられます。変更後の定義では、uc_mcontext
が直接レジスタ情報を含む構造体として扱われるため、余分なキャストが削除されています。これにより、コンパイラが正しい型でuc_mcontext
にアクセスできるようになり、ビルドエラーが解消されます。
SIG_CODE0
マクロの追加
変更後:
#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)
この新しいマクロは、シグナル情報構造体siginfo_t
(info
として渡される)からsi_code
フィールドの値を取得するためのものです。
info
はsiginfo_t
型へのポインタとして扱われます。(info)->si_code
は、siginfo_t
構造体のsi_code
フィールドにアクセスします。(uintptr)
へのキャストは、si_code
の値をポインタサイズ(通常は32ビットまたは64ビット)の符号なし整数型に変換しています。これは、Goランタイムがシグナルコードを内部的に処理する際に、ポインタとして扱えるような型を期待しているためと考えられます。- このマクロの追加は、GoランタイムがFreeBSD/ARM環境でシグナルハンドリングを行う際に、シグナルコードをより詳細に利用する必要が生じたことを示唆しています。例えば、特定のシグナルコードに基づいて異なるエラー処理を行う場合などに使用されます。
コアとなるコードの変更箇所
変更はsrc/pkg/runtime/signal_freebsd_arm.h
ファイルに集中しています。
--- a/src/pkg/runtime/signal_freebsd_arm.h
+++ b/src/pkg/runtime/signal_freebsd_arm.h
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#define SIG_REGS(ctxt) (((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext))\n
+#define SIG_REGS(ctxt) (((Ucontext*)(ctxt))->uc_mcontext)\n
#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).__gregs[0])
#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).__gregs[1])
@@ -25,3 +25,4 @@
#define SIG_TRAP(info, ctxt) (0)
#define SIG_ERROR(info, ctxt) (0)
#define SIG_OLDMASK(info, ctxt) (0)
+#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)\n
コアとなるコードの解説
SIG_REGS
マクロの修正
この修正は、FreeBSD/ARMにおけるシグナルコンテキストからのレジスタ情報へのアクセス方法を、Goランタイムが期待する形式に合わせるものです。uc_mcontext
は、ucontext_t
構造体内のマシンコンテキスト(レジスタ情報)を保持するフィールドです。以前は、このフィールドがSigcontext
という特定の型として扱われることを期待してキャストしていましたが、コードの再編成により、そのキャストが不要になったか、あるいは誤りになったため削除されました。これにより、コンパイラはuc_mcontext
をその本来の型(通常はmcontext_t
)として扱い、正しいオフセットと構造でレジスタにアクセスできるようになります。この変更がなければ、コンパイラは型ミスマッチや不正なメモリアクセスを検出し、ビルドエラーを引き起こしていました。
SIG_CODE0
マクロの追加
この新しいマクロは、シグナルハンドラに渡されるsiginfo_t
構造体から、シグナルコード(si_code
)を抽出するためのものです。si_code
は、シグナルが発生した具体的な原因を示す値であり、例えばSIGSEGV
の場合、不正なメモリアクセスの種類(例えば、存在しないアドレスへのアクセス、書き込み不可のページへの書き込みなど)を示すことがあります。Goランタイムがこれらの詳細なシグナルコードにアクセスできるようになったことで、より堅牢なエラーハンドリングやデバッグ情報の提供が可能になります。uintptr
へのキャストは、GoランタイムがCのポインタや整数値をGoのポインタとして扱えるようにするための一般的な慣習です。
これらの変更は、GoランタイムがFreeBSD/ARM環境でシグナルを正確に処理し、安定して動作するために不可欠なものです。
関連リンク
- Go言語の公式リポジトリ: https://github.com/golang/go
- Go CL (Change List) 7701046: https://golang.org/cl/7701046 (これは古いGo CLのURL形式であり、現在はhttps://go.dev/cl/7701046にリダイレクトされる可能性がありますが、2013年のコミットであるため、当時のURLが記載されています。)
参考にした情報源リンク
- FreeBSD
ucontext_t
man page (一般的な情報): https://www.freebsd.org/cgi/man.cgi?query=ucontext&sektion=3&format=html - FreeBSD
siginfo_t
man page (一般的な情報): https://www.freebsd.org/cgi/man.cgi?query=siginfo&sektion=2&format=html - ARM Architecture Reference Manual (一般的なARMアーキテクチャ情報): https://developer.arm.com/documentation/ddi0487/latest/
- Go言語のソースコード(
src/pkg/runtime
ディレクトリ) - Go言語のメーリングリストやIssueトラッカー(当時の議論を追跡する場合)```markdown
[インデックス 15774] ファイルの概要
このコミットは、Go言語のランタイムにおけるFreeBSD/ARMアーキテクチャ向けのシグナルハンドリングに関するビルドの問題を修正するものです。具体的には、以前のコード再編成(reorg)によって発生したビルドエラーを解消し、SIG_REGS
マクロの定義を修正し、SIG_CODE0
マクロを追加しています。
コミット
commit c89fc124c424b194af37c5ca71918f6b89a5c60e
Author: Russ Cox <rsc@golang.org>
Date: Thu Mar 14 17:50:07 2013 -0400
runtime: fix build for freebsd/arm after reorg
R=golang-dev
CC=golang-dev
https://golang.org/cl/7701046
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/c89fc124c424b194af37c5ca71918f6b89a5c60e
元コミット内容
runtime: fix build for freebsd/arm after reorg
変更の背景
このコミットは、GoランタイムのFreeBSD/ARMビルドが、以前のコード再編成("reorg")によって壊れてしまった問題を修正するために行われました。Go言語のランタイムは、異なるオペレーティングシステム(OS)やアーキテクチャ(CPU)に対応するために、OSやアーキテクチャ固有のコードを含んでいます。シグナルハンドリングは、プログラムが予期せぬイベント(例えば、不正なメモリアクセスや割り込み)に遭遇した際に、適切に処理するための重要なメカニズムです。
FreeBSD/ARM環境では、シグナルハンドリングのコンテキスト情報(レジスタの状態など)にアクセスするための特定の方法が必要です。以前のコード再編成により、このアクセス方法が変更されたか、または互換性が失われたため、ビルドエラーが発生するようになりました。このコミットは、その互換性の問題を解決し、FreeBSD/ARM環境でのGoランタイムのビルドを再び可能にすることを目的としています。
具体的には、FreeBSDのucontext_t
構造体内のuc_mcontext
フィールドへのアクセス方法が、以前のSigcontext
型へのキャストが不要になったか、あるいは不適切になった可能性があります。また、シグナル情報構造体(siginfo_t
)からシグナルコード(si_code
)を取得するための新しいマクロが必要になったことも背景にあります。
前提知識の解説
1. Goランタイム (Go Runtime)
Goランタイムは、Goプログラムの実行を管理するシステムです。これには、ガベージコレクション、スケジューリング、メモリ管理、そしてOSとのインタラクション(シグナルハンドリングを含む)などが含まれます。Goプログラムは、OSのネイティブスレッド上で動作しますが、GoランタイムがそのスレッドのスケジューリングやGoルーチンの管理を行います。
2. シグナルハンドリング (Signal Handling)
シグナルは、オペレーティングシステムがプロセスに非同期的に通知するイベントです。例えば、Ctrl+Cを押すとSIGINT
シグナルが、不正なメモリアクセスがあるとSIGSEGV
シグナルがプロセスに送信されます。プログラムはこれらのシグナルを捕捉し、特定の処理(シグナルハンドラ)を実行することができます。
3. ucontext_t
と mcontext_t
(FreeBSD)
ucontext_t
: POSIX標準で定義されている構造体で、シグナルハンドラが呼び出された時点でのプロセスの実行コンテキスト(レジスタ、シグナルマスク、スタックなど)を保存するために使用されます。これにより、シグナルハンドラから元の実行状態に復帰したり、別のコンテキストに切り替えたりすることが可能になります。mcontext_t
:ucontext_t
構造体の一部として含まれる構造体で、CPUのレジスタの状態(汎用レジスタ、プログラムカウンタ、スタックポインタなど)を保持します。アーキテクチャ(ARM、x86など)に依存するレジスタ情報が格納されます。FreeBSDでは、mcontext_t
は通常、__mcontext
という名前で定義され、その中に__gregs
(汎用レジスタ)などのフィールドが含まれます。
4. siginfo_t
(FreeBSD)
siginfo_t
構造体は、シグナルに関する追加情報を提供するものです。例えば、SIGSEGV
の場合、どのメモリアドレスでエラーが発生したか、SIGCHLD
の場合、どのプロセスが終了したかなどの情報が含まれます。si_code
フィールドは、シグナルが生成された原因を示すコードです。
5. Cプリプロセッサマクロ (#define
)
C言語のプリプロセッサマクロは、コンパイル前にテキスト置換を行う機能です。#define
ディレクティブを使って定義され、コードの可読性を高めたり、条件付きコンパイルを行ったりするために使用されます。このコミットでは、シグナルコンテキストからレジスタ情報にアクセスするためのマクロが定義されています。
6. ARMアーキテクチャ
ARM(Advanced RISC Machine)は、モバイルデバイスや組み込みシステムで広く使用されているRISC(Reduced Instruction Set Computer)ベースのCPUアーキテクチャです。レジスタの構成や命令セットがx86などとは異なります。
技術的詳細
このコミットの主要な変更点は、src/pkg/runtime/signal_freebsd_arm.h
ファイル内のSIG_REGS
マクロの定義修正と、SIG_CODE0
マクロの追加です。
SIG_REGS
マクロの修正
変更前:
#define SIG_REGS(ctxt) (((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext))
変更後:
#define SIG_REGS(ctxt) (((Ucontext*)(ctxt))->uc_mcontext)
この変更は、uc_mcontext
フィールドへのアクセス方法を修正しています。
ctxt
は、ucontext_t
型へのポインタとして扱われるべきです。したがって、まず(Ucontext*)(ctxt)
でucontext_t
型にキャストしています。((Ucontext*)(ctxt))->uc_mcontext
は、ucontext_t
構造体のuc_mcontext
フィールドにアクセスします。このフィールドは、FreeBSDのmcontext_t
型(またはそれに相当する型)です。- 変更前は、この
uc_mcontext
の結果をさらに(Sigcontext*)
にキャストしていました。これは、以前のFreeBSDのバージョンや、Goランタイムの内部的な型定義において、uc_mcontext
が直接Sigcontext
型として扱われることを期待していたか、あるいは互換性のためにそのようなキャストが必要だったことを示唆しています。 - しかし、"reorg"(コード再編成)によって、
uc_mcontext
の型が変更されたか、またはSigcontext
へのキャストが不要になった、あるいは不適切になったと考えられます。変更後の定義では、uc_mcontext
が直接レジスタ情報を含む構造体として扱われるため、余分なキャストが削除されています。これにより、コンパイラが正しい型でuc_mcontext
にアクセスできるようになり、ビルドエラーが解消されます。
SIG_CODE0
マクロの追加
変更後:
#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)
この新しいマクロは、シグナル情報構造体siginfo_t
(info
として渡される)からsi_code
フィールドの値を取得するためのものです。
info
はsiginfo_t
型へのポインタとして扱われます。(info)->si_code
は、siginfo_t
構造体のsi_code
フィールドにアクセスします。(uintptr)
へのキャストは、si_code
の値をポインタサイズ(通常は32ビットまたは64ビット)の符号なし整数型に変換しています。これは、Goランタイムがシグナルコードを内部的に処理する際に、ポインタとして扱えるような型を期待しているためと考えられます。- このマクロの追加は、GoランタイムがFreeBSD/ARM環境でシグナルハンドリングを行う際に、シグナルコードをより詳細に利用する必要が生じたことを示唆しています。例えば、特定のシグナルコードに基づいて異なるエラー処理を行う場合などに使用されます。
コアとなるコードの変更箇所
変更はsrc/pkg/runtime/signal_freebsd_arm.h
ファイルに集中しています。
--- a/src/pkg/runtime/signal_freebsd_arm.h
+++ b/src/pkg/runtime/signal_freebsd_arm.h
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#define SIG_REGS(ctxt) (((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext))\n
+#define SIG_REGS(ctxt) (((Ucontext*)(ctxt))->uc_mcontext)\n
#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).__gregs[0])
#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).__gregs[1])
@@ -25,3 +25,4 @@
#define SIG_TRAP(info, ctxt) (0)
#define SIG_ERROR(info, ctxt) (0)
#define SIG_OLDMASK(info, ctxt) (0)
+#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)\n
コアとなるコードの解説
SIG_REGS
マクロの修正
この修正は、FreeBSD/ARMにおけるシグナルコンテキストからのレジスタ情報へのアクセス方法を、Goランタイムが期待する形式に合わせるものです。uc_mcontext
は、ucontext_t
構造体内のマシンコンテキスト(レジスタ情報)を保持するフィールドです。以前は、このフィールドがSigcontext
という特定の型として扱われることを期待してキャストしていましたが、コードの再編成により、そのキャストが不要になったか、あるいは誤りになったため削除されました。これにより、コンパイラはuc_mcontext
をその本来の型(通常はmcontext_t
)として扱い、正しいオフセットと構造でレジスタにアクセスできるようになります。この変更がなければ、コンパイラは型ミスマッチや不正なメモリアクセスを検出し、ビルドエラーを引き起こしていました。
SIG_CODE0
マクロの追加
この新しいマクロは、シグナルハンドラに渡されるsiginfo_t
構造体から、シグナルコード(si_code
)を抽出するためのものです。si_code
は、シグナルが発生した具体的な原因を示す値であり、例えばSIGSEGV
の場合、不正なメモリアクセスの種類(例えば、存在しないアドレスへのアクセス、書き込み不可のページへの書き込みなど)を示すことがあります。Goランタイムがこれらの詳細なシグナルコードにアクセスできるようになったことで、より堅牢なエラーハンドリングやデバッグ情報の提供が可能になります。uintptr
へのキャストは、GoランタイムがCのポインタや整数値をGoのポインタとして扱えるようにするための一般的な慣習です。
これらの変更は、GoランタイムがFreeBSD/ARM環境でシグナルを正確に処理し、安定して動作するために不可欠なものです。
関連リンク
- Go言語の公式リポジトリ: https://github.com/golang/go
- Go CL (Change List) 7701046: https://golang.org/cl/7701046 (これは古いGo CLのURL形式であり、現在はhttps://go.dev/cl/7701046にリダイレクトされる可能性がありますが、2013年のコミットであるため、当時のURLが記載されています。)
参考にした情報源リンク
- FreeBSD
ucontext_t
man page (一般的な情報): https://www.freebsd.org/cgi/man.cgi?query=ucontext&sektion=3&format=html - FreeBSD
siginfo_t
man page (一般的な情報): https://www.freebsd.org/cgi/man.cgi?query=siginfo&sektion=2&format=html - ARM Architecture Reference Manual (一般的なARMアーキテクチャ情報): https://developer.arm.com/documentation/ddi0487/latest/
- Go言語のソースコード(
src/pkg/runtime
ディレクトリ) - Go言語のメーリングリストやIssueトラッカー(当時の議論を追跡する場合)