使用lldb使用Xamarin调试本机库

时间:2015-07-02 17:42:37

标签: ios xamarin xamarin.ios lldb xamarin-studio

Xamarin debugging documentation表示:

  

使用Xamarin Studio的本机调试支持来调试C#和   其他托管语言代码并在需要调试C时使用L​​LDB,   可能与您的Xamarin.iOS链接的C ++或Objective C代码   项目

但是我找不到任何关于如何使用LLDB来调试Xamarin应用程序的文档。如果我在iPhone模拟器中运行我的应用程序并尝试使用LLDB附加到它,我会收到以下错误:

(lldb) attach --pid 37993
Process 37993 exited with status = -1 (0xffffffff) lost connection

error: attach failed: lost connection

使用Xcode进行附加也不起作用。我尝试了attach的不同变体,但没有一个有效。

有人能指出我如何使用LLDB调试Xamarin应用程序的正确方向吗?此外,这是我可以在设备上做的事情,而不仅仅是在模拟器中?我没有找到有关如何使用LLDB附加到设备上的进程的任何信息。

更新

每当我使用debugserver连接到我的二进制文件时,lldb进程看起来都会崩溃。以下是debugserver崩溃报告的链接: https://www.dropbox.com/s/9lizhl2quj9n0cc/debugserver_2015-07-07-131423_gauss.crash?dl=0

更新2

当我在应用程序上运行dtruss时,它会打印系统调用,直到遇到

dtrace: error on enabled probe ID 2475 (ID 194: syscall::ptrace:return): invalid user access in action #5 at DIF offset 0

当某些内容调用时会发生ptrace(PT_DENY_ATTACH, 0, 0, 0);为什么调用PT_DENY_ATTACH

更新3

我跟踪了ptrace系统调用此函数:mono_assembly_init_with_opt这在程序生命的早期发生。所有函数都是调用ptrace,所以如果我只是从函数中提前返回,我可以使用lldb进行调试。

基本上,我可以这样做:

(lldb) process attach --name AppName --waitfor
# when the process starts
(lldb) b mono_assembly_init_with_opt    
(lldb) c
# when the thread breaks
(lldb) thread return 0
(lldb) c

现在我可以愉快地使用lldb进行调试。

但是,我不应该这样做。我的项目配置有什么问题(我可以使用lldb调试更简单的应用程序)还是Xamarin是邪恶的?

3 个答案:

答案 0 :(得分:2)

Mac OS X上的代码签名应用只有在其app plist中设置了特定属性时才能进行调试。你想要的东西看起来像:

<key>SecTaskAccess</key>
<array>
    <string>allowed</string>
    <string>debug</string>
</array>

您可以查看taskgated的手册页,以获得对此过程的简洁描述。

通常对于Xcode项目,此属性会被Xcode强制化并插入到您的调试版本中,因此您无需执行任何操作即可实现此目的。

我不知道Xamarin是如何工作的,但它可能没有设置此属性。在较旧的OS X系统上,root可以调试任何内容,因此您可以尝试sudo -s然后从那里进行调试。但是从Yosemite开始,不被调试的请求正在得到更广泛的尊重......

答案 1 :(得分:1)

您是否尝试过使用Activity Monitor中的pid?在Debug中运行它时,只需在Activity Monitor中的搜索框中键入您的应用程序名称。

如果它仍然无法工作,您可以尝试创建一个新项目并附加到该项目只是为了排除任何项目配置。

答案 2 :(得分:1)

这恰好是Xamarin在试用版中施加的限制。升级到付费许可证后,这不再是问题。尽管Xamarin的网站说:

  

当您开始Xamarin试用版时,您可以访问完整的Xamarin   商务功能设置为30天。

它显然不是完整的功能集,因为如果您使用的是本机库,它们会明确禁用将lldb附加到应用程序。我不确定这样做的原因,也许Xamarin的某个人可以发表评论。

<强>解释

感谢Jim Ingham指出我正确的方向。 Xamarin事件调试器附加到应用程序的方式是使用PT_DENY_ATTACH调用ptrace。此系统调用使进程能够拒绝调试请求。 (Detailed Explanation)。

此外,Xamarin不是直接调用ptrace函数,而是尝试使用syscall方法(link)隐藏调用。

解决方法

如果您确实需要调试应用并且仍在使用试用版,则此处是一种解决方法。 ptrace系统调用在函数mono_assembly_init_with_opt中进行,该函数在程序的生命周期的早期发生。该功能不做任何其他事情,可以跳过。由于函数在进程开始时被调用,我们需要在调用函数之前附加lldb。

步骤如下:

  1. 启动lldb并等待应用启动。
  2. 当应用开始时,为mono_assembly_init_with_opt
  3. 添加一个断点
  4. 恢复应用程序,当它停止在该功能时,提前返回而不执行该功能。
  5. 在此之后,您可以使用lldb或将Xcode附加到应用程序并照常调试您的本机代码。
  6. lldb中的步骤:

    (lldb) process attach --name AppName --waitfor
    (lldb) b mono_assembly_init_with_opt    
    (lldb) c
    # when the thread breaks
    (lldb) thread return 0
    (lldb) c