使用lldb使用Xamarin调试本机库

Kos*_*ukh 13 xamarin.ios ios lldb xamarin xamarin-studio

Xamarin调试文件表明:

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

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

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

error: attach failed: lost connection
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

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

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

Kos*_*ukh 1

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

开始 Xamarin 试用后,您可以在 30 天内使用完整的 Xamarin Business 功能集。

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

解释

感谢吉姆·英厄姆为我指明了正确的方向。Xamarin 事件调试器附加到应用程序的方式是通过使用PT_DENY_ATTACH. 此系统调用使进程能够拒绝调试请求。(详细解释)。

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

解决方法

如果您确实需要调试应用程序并且仍在使用试用版,那么这里有一个解决方法。函数中进行了ptrace系统调用mono_assembly_init_with_optptrace 系统调用是在程序生命周期早期发生的该函数不执行任何其他操作,可以跳过。由于该函数是在进程开始时调用的,因此我们需要在调用该函数之前附加 lldb。

步骤如下:

  1. 启动 lldb 并等待应用程序启动。
  2. 当应用程序启动时,添加一个断点mono_assembly_init_with_opt
  3. 恢复应用程序,当它停止在该函数时,提前返回而不执行该函数。
  4. 之后,您可以使用 lldb 或将 Xcode 附加到应用程序并像往常一样调试您的本机代码。

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
Run Code Online (Sandbox Code Playgroud)