【问题标题】:How to see what started a thread in Xcode?如何在 Xcode 中查看是什么启动了一个线程?
【发布时间】:2013-05-06 20:32:34
【问题描述】:

我被要求调试和改进一个复杂的多线程应用程序,该应用程序由我无权访问的人编写,它使用并发队列(GCD 和 NSOperationQueue)。我无权访问多线程架构的计划,也就是说,一份关于什么时候应该发生的高级设计文档。我需要制定这样的计划,以了解应用程序的工作原理和用途。

在运行代码和调试时,我可以在 Xcode 的 Debug Navigator 中看到正在运行的各种线程。 有没有一种方法可以确定特定线程在源代码中的哪个位置产生?有没有办法确定一个 NSOperation 属于哪个 NSOperationQueue?

例如,我可以在调试导航器(或使用 LLDB 的“线程回溯”命令)中看到线程的堆栈跟踪,但我可以查看的“最早”用户代码是被覆盖的 (NSOperation*) start 方法 -在堆栈中更早地退一步只是显示调用该方法的框架的汇编指令(例如__block_global_6_dispatch_call_block_and_release 等)。

我已经调查并寻求了各种调试方法,但没有成功。我得到的最接近的是方法调配的想法,但我认为这不会适用于排队的 NSOperation 线程。请原谅我的含糊之处:我知道我看起来像我一样努力,我可能问错了问题,因此可能还没有在我自己的脑海中清楚地形成这个问题,但我在问社区求助! 谢谢

【问题讨论】:

  • 另一个想法:这样的追踪可以通过 Instruments 实现吗?我已经查看了系统跟踪模板,但我还是看不到方法。
  • 是的,Instruments 将允许您使用 dtrace 来构建这种跟踪。

标签: multithreading debugging instruments grand-central-dispatch nsoperation


【解决方案1】:

我能想到的最好的方法是在dispatch_async-[NSOperation init]-[NSOperationQueue addOperation:] 等处设置断点。您可以配置这些断点来记录它们的堆栈跟踪,可能还有一些其他信息(例如dispatch_async 的块地址,或addOperation: 的队列和操作地址),然后继续运行。然后,当您对特定块的来源感到好奇时,您可以查看日志并查看调用了什么以及从哪里调用。 (这仍然需要一些侦探工作。)

如果断点方法太慢,您也可以使用dtrace 完成类似的操作。

【讨论】:

  • 谢谢你,杰西 - 这很有帮助。是的,我希望除了拼凑断点输出之外还有一种方法。我没有任何 dtrace 的经验,所以我现在正在研究。
  • dtrace 有点复杂;如果您将断点配置为立即继续,您可能可以避免使用断点。 (右键单击它们,在 Xcode 中选择“编辑断点”。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-21
  • 1970-01-01
  • 2017-12-10
  • 2019-01-03
  • 2010-12-18
  • 1970-01-01
相关资源
最近更新 更多