pthread_kill中的svc#128意外地进入调试器?

时间:2015-01-04 18:35:20

标签: xcode assembly arm svc j2objc

我在Xcode中看到调试器的意外中断,与调用pthread_kill的svc #128 ARM指令相关,以指示另一个线程。我已经在iOS上看到了许多与此问题相关的StackOverflow问题 - 但它们对我没有帮助。在这种情况下,执行Debug-> Continue(^⌘Y)会重复解决问题并继续执行,而不会产生任何明显的副作用。此外,如果它在调试器之外运行,那么应用程序工作正常。我的目标是了解为什么会发生这种情况,并避免进入调试器,除非是在预期的情况下。

是否有Xcode设置,我可能不小心设置了这些信号中断?

我正在使用谷歌的Java到Objective-C Transpiler(j2objc),虽然其他iOS开发者已经提到这个与j2objc无关的问题,所以我不相信这是原因。当j2objc Java运行时环境仿真项目发出其他阻塞线程信号时,就会发生这种情况。它始终有3个线程发出信号。在进行Debug->继续三次后,程序执行继续进行,没有问题或明显的副作用。项目中没有断点。

该应用程序在启动时生成另一个使用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代码:

https://github.com/google/j2objc/blob/765354b620b2c0248945b27062209620d4cf5e40/jre_emul/android/libcore/luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java#L89

+ (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调用 - 避免问题,但显然不是解决方法让socket打开

1 个答案:

答案 0 :(得分:1)

有一个技巧要求Xcode忽略这些信号。我很好奇为什么Xcode默认配置为中断信号,但你去了。请注意,该方法根据您使用的语言而有所不同 - 我编辑它以将示例扩展为Swift:

Permanently configuring LLDB (in Xcode 4.3.2) not to stop on signals