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

[インデックス 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_tmcontext_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_tinfoとして渡される)からsi_codeフィールドの値を取得するためのものです。

  • infosiginfo_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環境でシグナルを正確に処理し、安定して動作するために不可欠なものです。

関連リンク

参考にした情報源リンク

[インデックス 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_tmcontext_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_tinfoとして渡される)からsi_codeフィールドの値を取得するためのものです。

  • infosiginfo_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環境でシグナルを正確に処理し、安定して動作するために不可欠なものです。

関連リンク

参考にした情報源リンク