简体   繁体   English

svc#128在pthread_kill中意外闯入调试器?

[英]svc #128 in pthread_kill unexpectedly breaking in to debugger?

I'm seeing unexpected breaks in to the debugger in Xcode, related to the svc #128 ARM instruction from a call to pthread_kill to signal another thread. 我看到Xcode中的调试器出现意外中断,与通过调用pthread_kill发出信号通知另一个线程的svc #128 ARM指令有关。 I've seen this for a number of StackOverflow questions related to this issue on iOS - but they weren't helpful for me. 我已经在iOS上与该问题相关的许多StackOverflow问题中看到了这一点-但它们对我没有帮助。 In this case, doing Debug->Continue (^⌘Y) repeatedly resolves the problem and execution continues without any apparent side effects. 在这种情况下,反复执行Debug-> Continue(^⌘Y)可解决该问题,并且继续执行不会有任何明显的副作用。 Also, if it's run outside of the debugger, then the app works fine. 另外,如果它在调试器之外运行,则该应用程序可以正常运行。 My goal is to understand why this is happening and avoid breaking in to the debugger except when intended. 我的目标是了解为什么会发生这种情况,并避免闯入调试器,除非是有意的情况。

Is there an Xcode setting that I might have accidentally set that breaks on these signals? 是否有我可能不小心设置的Xcode设置会在这些信号上中断?

I'm using Google's Java to Objective-C Transpiler (j2objc), though other iOS devs have mentioned this issue unrelated to j2objc, so I don't believe that's the cause. 我正在使用Google的Java到Objective-C Transpiler(j2objc),尽管其他iOS开发人员也提到了与j2objc无关的问题,所以我不认为这是原因。 It occurs when the j2objc Java Runtime Environment Emulation project is signaling other blocked threads. 当j2objc Java运行时环境仿真项目向其他阻塞线程发出信号时,就会发生这种情况。 It consistently has 3 threads to signal. 它始终具有3个线程来发出信号。 After doing Debug->Continue three times, then the program execution carries on without issue or apparent side effect. 在执行Debug-> Continue三遍之后,程序执行就不会出现问题或明显的副作用。 There are no breakpoints in the project. 项目中没有断点。

The app spawns another thread at startup that uses the Java DatagramSocket class. 该应用程序在启动时会生成另一个使用Java DatagramSocket类的线程。 The Java code works correctly. Java代码正常工作。 The transpiled Objective-C code also works correctly except for the annoying breaks in to the debugger. 转译的Objective-C代码也可以正常工作,除了调试器的烦人之处。

This is the Stack Frame at interrupt: 这是中断时的堆栈帧:

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>...

Local assembly in kernel pthread_kill method... 内核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

The closest non-kernel function in the stack frame is signalBlockedThreads . 堆栈帧中最接近的非内核函数是signalBlockedThreads When my code closes the socket, signalBlockedThreads iterates through all the threads, looking for those blocked against a specific file descriptor (I presume this corresponds to the port number that was just closed). 当我的代码关闭套接字时, signalBlockedThreads遍历所有线程,查找针对特定文件描述符阻塞的线程(我想这与刚刚关闭的端口号相对应)。 For those relevant blocked threads, they're each signaled with pthread_kill. 对于那些相关的阻塞线程,每个线程都带有pthread_kill信号。 The method code is copied below. 方法代码复制如下。

For the file link, even though this is a Java file, it has embedded Objective-C code that is preserved by the j2objc transpiler: 对于文件链接,即使这是一个Java文件,它也嵌入了由j2objc转译器保留的Objective-C代码:

https://github.com/google/j2objc/blob/765354b620b2c0248945b27062209620d4cf5e40/jre_emul/android/libcore/luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java#L89 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);
}

Debug attempts without success: * Add and remove "All Exceptions" breakpoint - nothing revealed by this * Remove closeSocket call - averts issue but obviously not a solution to leave socket open 调试尝试未成功:*添加和删除“所有异常”断点-此操作未显示任何内容*删除closeSocket调用-避免出现问题,但显然不是使套接字保持打开状态的解决方案

There's a trick to asking Xcode to ignore the signals. 要求Xcode忽略信号有一个技巧。 I'm curious as to why Xcode is configured by default to interrupt on signals but there you go. 我很好奇为什么默认情况下将Xcode配置为在信号上中断,但是你去了。 Note that the method varies according to the language that you're using - I've edited it to extend the example to Swift: 请注意,该方法根据您使用的语言而有所不同-我已经对其进行了编辑,以将示例扩展到Swift:

Permanently configuring LLDB (in Xcode 4.3.2) not to stop on signals 永久配置LLDB(在Xcode 4.3.2中)不停止信号

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM