[インデックス 12997] ファイルの概要
このコミットは、GoランタイムがDarwin (macOS) 環境でDYLD_INSERT_LIBRARIES
環境変数が設定されている場合、またはbsdthread_register
システムコールが失敗した場合に、より適切なエラーメッセージを提供するように改善するものです。これにより、ユーザーは問題の原因を特定しやすくなります。
コミット
commit 44fd1d1a6aee68023be292a6f856991af3f0d4c8
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Mon Apr 30 15:55:07 2012 -0400
runtime: give proper messages when user defined DYLD_INSERT_LIBRARIES on Darwin
also gives clear error when bsdthread_register fails on Darwin
Fixes #2992.
R=rsc, krautz
CC=golang-dev
https://golang.org/cl/5966067
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/44fd1d1a6aee68023be292a6f856991af3f0d4c8
元コミット内容
runtime: give proper messages when user defined DYLD_INSERT_LIBRARIES on Darwin
also gives clear error when bsdthread_register fails on Darwin
Fixes #2992.
変更の背景
この変更の背景には、GoプログラムがmacOS上で実行される際に発生する可能性のある、特定の環境設定やシステムコール失敗時のデバッグの困難さがありました。
-
DYLD_INSERT_LIBRARIES
による問題の明確化:DYLD_INSERT_LIBRARIES
はmacOSのダイナミックリンカ(dyld
)が、プログラム自身の依存関係がロードされる前に、指定されたダイナミックライブラリ(.dylib
ファイル)をプロセスにロードすることを可能にする環境変数です。これはデバッグ、テスト、またはカスタム機能の実装に便利ですが、悪意のあるコードインジェクションにも利用される可能性があります。Goプログラムがこの環境変数の影響を受けると、予期せぬ動作やクラッシュを引き起こすことがありましたが、その際のエラーメッセージが不明瞭でした。ユーザーがこの環境変数を設定している場合に、Goランタイムがより具体的なエラーメッセージを出すことで、問題の特定と解決を容易にすることが求められました。 -
bsdthread_register
失敗時のエラーハンドリング改善:bsdthread_register
はDarwin(macOS)のシステムコールであり、スレッドシステムの設定に使用されます。Goランタイムは、macOS上でスレッドを管理するためにこのシステムコールを利用します。このシステムコールが何らかの理由で失敗した場合、Goプログラムはクラッシュする可能性がありましたが、その際のエラーメッセージが不十分でした。特に、古いGoバージョンと新しいmacOSバージョンの間の互換性の問題や、セキュリティソフトウェアの干渉などが原因でこのエラーが発生することがありました。このコミットは、bsdthread_register
が失敗した場合に、より明確なエラーメッセージを提供することで、ユーザーが根本原因を理解し、対処できるようにすることを目的としています。
これらの改善は、GoプログラムのmacOS環境での堅牢性とデバッグ体験を向上させるために行われました。
前提知識の解説
このコミットを理解するためには、以下の概念について知っておく必要があります。
-
Goランタイム (Go Runtime): Go言語で書かれたプログラムを実行するための環境です。メモリ管理(ガベージコレクション)、ゴルーチン(軽量スレッド)のスケジューリング、チャネルによる通信、システムコールへのインターフェースなど、プログラムの実行に必要な低レベルの機能を提供します。
-
Darwin (macOS): AppleのオペレーティングシステムであるmacOSの基盤となるUNIX系OSです。Goランタイムは、このDarwin上で動作するために、Darwin固有のシステムコールやAPIを利用します。
-
DYLD_INSERT_LIBRARIES
: macOSの環境変数で、ダイナミックリンカ(dyld
)に対して、指定された共有ライブラリ(.dylib
ファイル)を、アプリケーションの起動時にそのアプリケーションのプロセス空間に強制的にロードさせるためのものです。これは、既存のアプリケーションの動作を変更したり、デバッグフックを挿入したりする際に使用されます。しかし、セキュリティ上のリスクも伴い、悪用される可能性もあります。macOSのSystem Integrity Protection (SIP) やHardened Runtimeなどのセキュリティ機能は、このメカニズムの悪用を防ぐために導入されています。 -
bsdthread_register
: Darwinカーネルが提供するシステムコールの一つです。これは、ユーザー空間のスレッドライブラリ(例えば、Goランタイムが内部的に使用するスレッド管理メカニズム)が、カーネルに対して自身を登録するために使用されます。これにより、カーネルはユーザー空間のスレッドの状態を適切に管理し、シグナルハンドリングやデバッグなどの機能を提供できるようになります。GoランタイムがmacOS上でゴルーチンを効率的にスケジューリングし、システムリソースにアクセスするためには、このbsdthread_register
が正常に機能することが不可欠です。 -
Cgo: Go言語の機能の一つで、C言語のコードをGoプログラムから呼び出すことを可能にします。Cgoを使用すると、Goの標準ライブラリでは提供されていないOS固有のAPIや、既存のCライブラリを利用できます。Cgoを使用する場合、GoランタイムはC言語のpthreadライブラリと連携してスレッドを管理することがあります。
技術的詳細
このコミットは、GoランタイムがmacOS上でスレッドを初期化する際の堅牢性を高めるためのものです。
Goランタイムは、macOS上で独自の軽量スレッド(ゴルーチン)を管理するために、基盤となるOSのスレッド機能を利用します。この際、bsdthread_register
システムコールを呼び出して、Goランタイムのスレッド管理メカニズムをカーネルに登録します。
変更前は、bsdthread_register
の呼び出しがruntime·osinit
関数内で行われていました。この関数は、環境変数を読み込む前に実行されるため、DYLD_INSERT_LIBRARIES
のような環境変数の影響を考慮する機会がありませんでした。また、bsdthread_register
が失敗した場合、ランタイムは単にクラッシュするだけで、具体的なエラーメッセージを提供していませんでした。
このコミットでは、以下の技術的な変更が加えられています。
-
bsdthread_register
の呼び出しタイミングの変更:runtime·bsdthread_register
の呼び出しが、runtime·osinit
からruntime·goenvs
関数内に移動されました。runtime·goenvs
は、環境変数が読み込まれた後に実行されるため、ランタイムはDYLD_INSERT_LIBRARIES
のような環境変数の存在をチェックできるようになります。 -
bsdthread_register
の戻り値の利用:runtime·bsdthread_register
関数のシグネチャが変更され、void
からint32
を返すようになりました。これにより、システムコールの成功/失敗を示す戻り値を利用して、エラーハンドリングを行うことが可能になります。アセンブリコード(sys_darwin_386.s
とsys_darwin_amd64.s
)も、この戻り値を適切に処理するように修正されています。具体的には、システムコールが失敗した場合(キャリーフラグがセットされない場合)、AX
レジスタに格納されたエラーコードを否定(NEGL AX
)して返し、成功した場合は0
を返すように変更されています。 -
エラーメッセージの改善:
runtime·thread_darwin.c
内のruntime·goenvs
関数で、runtime·bsdthread_register()
の戻り値をチェックし、非ゼロ(エラー)の場合にエラーメッセージを生成するロジックが追加されました。- もし
DYLD_INSERT_LIBRARIES
環境変数が設定されている場合、runtime: bsdthread_register error (unset DYLD_INSERT_LIBRARIES)
という具体的なメッセージをスローします。これは、DYLD_INSERT_LIBRARIES
がスレッド登録の失敗の原因である可能性が高いことを示唆し、ユーザーにその環境変数を解除するよう促します。 DYLD_INSERT_LIBRARIES
が設定されていない場合でもbsdthread_register
が失敗した場合は、runtime: bsdthread_register error
という一般的なエラーメッセージをスローします。
- もし
-
Cgoとの連携: Cgoを使用している場合は、GoランタイムがCのpthreadライブラリにスレッド作成のコールバックをインストールさせる必要があるため、
runtime·iscgo
フラグをチェックしてbsdthread_register
の呼び出しをスキップするロジックは維持されています。
これらの変更により、GoランタイムはmacOS上でのスレッド初期化に関する問題をより適切に診断し、ユーザーに具体的な解決策を提示できるようになりました。
コアとなるコードの変更箇所
このコミットで変更された主要なファイルとコードの変更箇所は以下の通りです。
-
src/pkg/runtime/os_darwin.h
:runtime·bsdthread_register
関数の宣言が、void
を返すものからint32
を返すものに変更されました。--- a/src/pkg/runtime/os_darwin.h +++ b/src/pkg/runtime/os_darwin.h @@ -6,7 +6,7 @@ #define SIG_IGN ((void*)1) int32 runtime·bsdthread_create(void*, M*, G*, void(*)(void)); -void runtime·bsdthread_register(void); +int32 runtime·bsdthread_register(void); int32 runtime·mach_msg_trap(MachHeader*, int32, uint32, uint32, uint32, uint32, uint32); uint32 runtime·mach_reply_port(void); int32 runtime·mach_semacquire(uint32, int64);
-
src/pkg/runtime/sys_darwin_386.s
(32-bit Intel アセンブリ):runtime·bsdthread_register
のシステムコール呼び出し後のエラーハンドリングが変更されました。以前はエラー時にクラッシュしていましたが、エラーコードを返すように修正されました。--- a/src/pkg/runtime/sys_darwin_386.s +++ b/src/pkg/runtime/sys_darwin_386.s @@ -268,8 +268,10 @@ TEXT runtime·bsdthread_register(SB),7,$40 MOVL $0, 20(SP) // targetconc_ptr MOVL $0, 24(SP) // dispatchqueue_offset INT $0x80 - JAE 2(PC) - MOVL $0xf1, 0xf1 // crash + JAE 3(PC) + NEGL AX + RET + MOVL $0, AX RET // Invoke Mach system call.
-
src/pkg/runtime/sys_darwin_amd64.s
(64-bit Intel アセンブリ):runtime·bsdthread_register
のシステムコール呼び出し後のエラーハンドリングが変更されました。32-bit版と同様に、エラー時にクラッシュする代わりにエラーコードを返すように修正されました。--- a/src/pkg/runtime/sys_darwin_amd64.s +++ b/src/pkg/runtime/sys_darwin_amd64.s @@ -265,8 +265,10 @@ TEXT runtime·bsdthread_register(SB),7,$0 MOVQ $0, R9 // dispatchqueue_offset MOVQ $(0x2000000+366), AX // bsdthread_register SYSCALL - JCC 2(PC) - MOVL $0xf1, 0xf1 // crash + JCC 3(PC) + NEGL AX + RET + MOVL $0, AX RET // Mach system calls use 0x1000000 instead of the BSD's 0x2000000.
-
src/pkg/runtime/thread_darwin.c
:runtime·osinit
からruntime·bsdthread_register
の呼び出しが削除され、runtime·goenvs
関数内に移動されました。runtime·goenvs
内で、runtime·bsdthread_register()
の戻り値をチェックし、エラー時にDYLD_INSERT_LIBRARIES
の有無に応じて異なるエラーメッセージをスローするロジックが追加されました。--- a/src/pkg/runtime/thread_darwin.c +++ b/src/pkg/runtime/thread_darwin.c @@ -50,11 +50,8 @@ runtime·semacreate(void) void runtime·osinit(void) { - // Register our thread-creation callback (see sys_darwin_{amd64,386}.s) - // but only if we're not using cgo. If we are using cgo we need - // to let the C pthread libary install its own thread-creation callback. - if(!runtime·iscgo) - runtime·bsdthread_register(); + // bsdthread_register delayed until end of goenvs so that we + // can look at the environment first. // Use sysctl to fetch hw.ncpu. uint32 mib[2]; @@ -75,6 +72,18 @@ void runtime·goenvs(void) { runtime·goenvs_unix(); + + // Register our thread-creation callback (see sys_darwin_{amd64,386}.s) + // but only if we're not using cgo. If we are using cgo we need + // to let the C pthread libary install its own thread-creation callback. + if(!runtime·iscgo) { + if(runtime·bsdthread_register() != 0) { + if(runtime·getenv("DYLD_INSERT_LIBRARIES")) + runtime·throw("runtime: bsdthread_register error (unset DYLD_INSERT_LIBRARIES)"); + runtime·throw("runtime: bsdthread_register error"); + } + } + } void
コアとなるコードの解説
このコミットの核心は、GoランタイムがmacOS上でスレッドを初期化する際の挙動をより堅牢にし、デバッグを容易にすることにあります。
-
os_darwin.h
の変更:runtime·bsdthread_register
関数の戻り値の型をvoid
からint32
に変更したことは、この関数がシステムコールからの結果(成功/失敗を示すエラーコード)を返すことを可能にするための基盤です。これにより、呼び出し元はシステムコールの成否をプログラム的に判断できるようになります。
-
sys_darwin_386.s
およびsys_darwin_amd64.s
の変更:- これらのアセンブリファイルは、それぞれ32ビットおよび64ビットのmacOSアーキテクチャにおける
bsdthread_register
システムコールの実際の呼び出しを定義しています。 - 変更前は、システムコールが失敗した場合(
JAE
またはJCC
命令でキャリーフラグがセットされない場合)、MOVL $0xf1, 0xf1
のような命令で意図的にクラッシュさせていました。これは、致命的なエラーが発生したことを示すための原始的な方法でした。 - 変更後は、システムコールが失敗した場合に、
NEGL AX
命令を使用してAX
レジスタに格納されたエラーコードを否定し、それを関数の戻り値として返します。成功した場合はMOVL $0, AX
で0
を返します。これにより、Cコード側でシステムコールの結果を数値として受け取り、より詳細なエラーハンドリングを行うことが可能になります。
- これらのアセンブリファイルは、それぞれ32ビットおよび64ビットのmacOSアーキテクチャにおける
-
thread_darwin.c
の変更:bsdthread_register
呼び出しの遅延: 以前はruntime·osinit
でbsdthread_register
を呼び出していましたが、これをruntime·goenvs
に移動しました。runtime·goenvs
は環境変数が読み込まれた後に実行されるため、DYLD_INSERT_LIBRARIES
のような環境変数の存在をチェックする機会が得られます。これは、環境変数がスレッド登録の失敗に影響を与える可能性があるため、非常に重要です。- エラーチェックとメッセージの改善:
if(runtime·bsdthread_register() != 0)
:bsdthread_register
が非ゼロの値を返した場合(つまりエラーが発生した場合)に、エラー処理ブロックに入ります。if(runtime·getenv("DYLD_INSERT_LIBRARIES"))
: ここでDYLD_INSERT_LIBRARIES
環境変数が設定されているかどうかをチェックします。runtime·getenv
は、指定された環境変数の値を取得するGoランタイムの内部関数です。- もし
DYLD_INSERT_LIBRARIES
が設定されていてbsdthread_register
が失敗した場合、runtime·throw("runtime: bsdthread_register error (unset DYLD_INSERT_LIBRARIES)")
というメッセージでパニックを発生させます。このメッセージは、DYLD_INSERT_LIBRARIES
が問題の原因である可能性が高いことを明確に示し、ユーザーにその環境変数を解除するよう促します。 DYLD_INSERT_LIBRARIES
が設定されていない場合でもbsdthread_register
が失敗した場合は、runtime·throw("runtime: bsdthread_register error")
という一般的なエラーメッセージでパニックを発生させます。これは、他の未知の原因による失敗を示唆します。
- Cgoの考慮:
if(!runtime·iscgo)
のチェックは引き続き行われます。これは、Cgoを使用しているGoプログラムでは、GoランタイムがCのpthreadライブラリにスレッド作成のコールバックをインストールさせる必要があるため、Goランタイム自身がbsdthread_register
を呼び出す必要がないためです。
これらの変更により、GoランタイムはmacOS上でのスレッド初期化に関する問題をより詳細に診断し、特にDYLD_INSERT_LIBRARIES
が関与している場合に、ユーザーに具体的なデバッグのヒントを提供できるようになりました。
関連リンク
- Go issue #2992: https://github.com/golang/go/issues/2992
- Go CL 5966067: https://golang.org/cl/5966067
参考にした情報源リンク
-
DYLD_INSERT_LIBRARIES
に関する情報:- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGZMXylIKyy3A9bdHjdfnORwWHL0MUHaeN57f8wwy0WFkQx6ZYmhr4xwfImoaXi38DYtFUAFQ__f6rfkSuWBe5nP-IGbbozdaebh2fe9V1KVcBgG8p-mgKxvHQixhfAguSRQx9hn9UJsbTnHVlz-X0Eq2y_KjaWLjuGH8X5S0CaQ9rBNgVpdblECXphizI1UzwnHIcyTOnCARei7Vg==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH85RsOxhD5ipcDd49GSRf4FTyLxw3ECIt1BV4n4ZAQCZAqrKMEZyuDMHzsoINlTXr0KWcJNFrP7FCiyD-QFSQ4vzidpPlI-cuUP6qdtqAev-br-War-7FJLX5PzUjd9EUf6Xr8u5Z66QEs1EqE-H7tuQOwQPtt_BNkt6-zOHCx8D9mRjdJkYoDFZdX2nVcpGO-I2JDd_ChkJfxIt0oKNcrbT_9Y_I8V34c4UJAAl3JFuVt9jw=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGqhPluVXgtq5GZz9TeENdUFKbw5XNCTiIjBhiyWWxlMFbueuePNqD2o-VBQjvNCrd-TdsJ_YAUAYpARcDvOXARNwBViVf2FlpBke4i9E54jBciRVDOXFjF___tTCNz6I0fqTKFvHWEPyNH9bsZRJaPR9tbU3lpN-dJxIIOMEB1AkPz1UfC
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGSOFp7kNncek3CYl_Sid0s8EbBA_jgpFxqynk377g3tQhlL1mJ8YpI62x1gi9HIVljdfpbMfZOzPR-8Qh1SXXKynCoUvdg6cjmOn8yYPfgZPeysBzZGi1rwEBlXyHXC1PkzIqxa0KtlvlH8HmcgzzgsGoTAM2gz1wDBF2srz65KE=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFxkrmQE7xgXAZLxAzHIKlThDk0jg0rVlimUPcAslZNqzOh36S3pHVCtYijCU0NbkGS9DKe8jfpGrGlntHGeMQRTFEkcWD_aaA-lGHZVLFyEt4tWvBTfEuJDhvhC2ZzJz_A5b1WoOSPZRGpgpePPP5Zb_5xquk26bT8GMKi
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHwAWjZXvCBswL0lO--7jzcWDy9rkwTw4fKo87n4tmGV__1C7xSnj5U9It0yL_OOdyXfXLACy0O2BaSJ8IjF5nbYCwf6w7TcidL1w3fCn58m2C9MfB8gUuRSG-QnUZZneFmaas3rcaO0E78KkixrtSK-
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHaNhzByeSIHo5sMg657i055HuaishhIEJEhXOmKPLfVXjMAEhUqg2aLqbhR2Bh2uxnbeJYGKDN9tz3ivekOifuXokVMuA1USlzBeFUSu8zeem3YyLwawAKPShsouJECFmRVDmF
-
bsdthread_register
に関する情報:- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFK0mKmBqzG-FCDUDLCKduCxsa5QanUc-wpeh23DW-nyq1Fx6m_z0DtnGFIOfpaH309VmL4JlqHloKeGP8o_SiHZJ53ONCWDZ6oFYfDnNc6AUJ09a-3uLg-gmSDan_WEn6wyjSx3N3uSV99zpOXiME=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGUr46dBHl2Y-CzJtIt9Y8m7J4KV24RkAd6SDebFs_L1kkYMxASNbathTW0yJywJxcEB2e13kChA63FXMRVLC5NS2sk3_vYI4Xh1aH3ydwLcRt1aJ442NJ7uammU7wMCumGv0yZvYEUyIltQfGOXrUoFuDOuIdsW956idxi7TRTjhnL4I8W8JG24sd8lsGOS97GGWKIuYUtcGdWi7pWpz5D
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFM_Fq7Kw5ZcR9WhiPfE4lPCdYYOjueF6VAGSkyLRopLGQVzvrDkUVZCIF5HCPhuiebiEIlf9iyBh5XrVmdYqR2cfLmarANLlv9UY04awKMft752Cr2mTj0wFEdzCV86xmsOL_YHO0zTZnusFvIOA8IUzU2F8M3HBJf7QeUlq8_CHb_QBV-kv9KOtPKiQfko4nf1hzAw1xPjUfGJe4pH2-KDllu8TC9yLCOS0c2EsT-MEoXzWCKOQ==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGGhFIM_29AggATQrKmq7trKSyL0VncnfZxbXeXPIGiSV5ooed98cOp_Cssl5EZKItYE-DK15J6ILa6NKZNprdfWyFUdi6i8ywZLVhWZOlc21sBuUt6P005-1UQZ0-zLmPNYpSd_UrAqFYXFg==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEPslH6-WxeWpJKO-FbiWWeWQmnf6Y3ZuVrvxklzCaWAJ9Jrt5Fd6ISSbO4DmsG1WftkXyYwoaH3c19EX6_8aOnXq_kPTKhMw5z0tbOCGZWfoF_V31KjiDq5CwW13jKedEKwGxLQkVZki2XCyG3QAnOICuFe9vWQ2P4H6nth_2mUDkT1WnXNgS8ONsimChtTV7U_mQdqgtOcLjmMR2NPh3ys5unkCbleigulpgvzcP5ZDBpKg==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQG8ckCbPFNq90ILo4oHuK_Ib-4-wyW8rfD9qZJ0gpK03Fooam5mT8bGlp4583bahPbCCYzm54yvzl-D-EL95KDGC2Flt-xX-4u1eEPGqJE3WOf-N3NA42TTIVOwMw7pKPs3V-A=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGjvC6_h95ufJn5THUD1Plm430JFpGBkVjwwyHnoe5WZMHRoAz-L_nasim5Vx7ikwBO6v8i7EQr9vlwdndJe_bqTY4x5KJBLIVFX1x9RgR9QLUToBRT3hI4hmpbhnOZJRbMvaiRE-9Rz1tdSpvubbQsMFzmfGbs3yIKHkMG1sakKe-fV8T45-4=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFjQrJeJYZHFqnvDcFLxXX2ooU50I-TF0vG5oDWLZouS3hI1GKp0h4SJmYe-OeUYpZ027GyPX0tsk9OI_HXzTDA3g6GQKOwNtMk392hpFYl4qKDS7qJ-h6Yh8fpfPF4EgfuFacyDDTcAkQft4ZVjBhpcj4KcoQeYF3uAgvOAtSkoosVHwzvQo86plg-A==