svc #128
別のスレッドにシグナルを送るための pthread_kill の呼び出しからの ARM 命令に関連して、Xcode のデバッガーに予期しない中断が見られます。iOS でのこの問題に関連する StackOverflow の質問でこれを見てきましたが、役に立ちませんでした。この場合、Debug->Continue (^⌘Y) を繰り返し実行すると、問題が解決され、明らかな副作用なしに実行が続行されます。また、デバッガーの外部で実行されている場合、アプリは正常に動作します。私の目標は、なぜこれが起こっているのかを理解し、意図した場合を除いてデバッガーに侵入しないようにすることです。
これらのシグナルで壊れる、誤って設定した可能性のある Xcode 設定はありますか?
私は Google の Java to Objective-C Transpiler (j2objc) を使用していますが、他の iOS 開発者は j2objc とは関係のないこの問題について言及しているので、それが原因だとは思いません。これは、j2objc Java ランタイム環境エミュレーション プロジェクトが他のブロックされたスレッドを通知しているときに発生します。一貫してシグナルするスレッドが 3 つあります。Debug->Continue を 3 回実行した後、プログラムの実行は問題や明らかな副作用なしに続行されます。プロジェクトにブレークポイントはありません。
アプリは、起動時に Java DatagramSocket クラスを使用する別のスレッドを生成します。Java コードは正しく機能します。トランスパイルされた Objective-C コードも、デバッガーへの煩わしいブレークを除いて正しく動作します。
これは割り込み時のスタック フレームです。
main (1)Queue : com.apple.main-thread (serial)
#0 0x0000000195557270 in __pthread_kill ()
#1 0x00000001955f5228 in pthread_kill ()
// Java Runtime Environment Emulation
#2 0x00000001002f7898 in +[AsynchronousSocketCloseMonitor signalBlockedThreads:] ()
#3 0x00000001002f9754 in LibcoreIoIoBridge_closeSocketWithJavaIoFileDescriptor_ ()
#4 0x00000001001f4894 in -[JavaNetPlainDatagramSocketImpl close] ()
// My Code
#5 0x000000010016db88 in <my code>...
カーネル pthread_kill メソッドのローカル アセンブリ...
libsystem_kernel.dylib`__pthread_kill:
0x195557268: movz x16, #328
0x19555726c: svc #128
// The debugger lands on the following line but I think svc #128 is the cause
0x195557270: b.cc 0x195557288 ; __pthread_kill + 32
0x195557274: stp fp, lr, [sp, #-16]!
0x195557278: mov fp, sp
0x19555727c: bl 0x19553e59c ; cerror_nocancel
0x195557280: mov sp, fp
0x195557284: ldp fp, lr, [sp], #16
0x195557288: ret
スタック フレームで最も近い非カーネル関数は ですsignalBlockedThreads
。私のコードがソケットを閉じると、signalBlockedThreads
すべてのスレッドを繰り返し処理し、特定のファイル記述子に対してブロックされているスレッドを探します (これは、閉じたばかりのポート番号に対応すると思います)。関連するブロックされたスレッドについては、それぞれ pthread_kill で通知されます。メソッドコードを以下にコピーします。
ファイル リンクの場合、これは Java ファイルですが、j2objc トランスパイラーによって保持される Objective-C コードが埋め込まれています。
+ (void)signalBlockedThreads:(int)fd {
pthread_mutex_lock(&blockedThreadListMutex);
for (AsynchronousSocketCloseMonitor* it = blockedThreadList; it != NULL; it = it->mNext) {
if (it->mFd == fd) {
// MY ADDED COMMENT: BLOCKED_THREAD_SIGNAL == SIGUSR2 in this code
pthread_kill(it->mThread, BLOCKED_THREAD_SIGNAL);
// Keep going, because there may be more than one thread...
}
}
pthread_mutex_unlock(&blockedThreadListMutex);
}
成功しないデバッグ試行: * 「すべての例外」ブレークポイントを追加および削除 - これによって何も明らかにされない * closeSocket 呼び出しを削除 - 問題を回避しますが、明らかにソケットを開いたままにする解決策ではありません