尝试执行以下命令
lldb -o 'process connect connect://[fd42:af35:2043::1]:50773'
在 MacOS
zsh
终端上会导致 lldb
处于“挂起”状态。我无法以任何方式取消它。我必须杀死 zsh
实例。
但是,直接在
process connect connect://[fd42:af35:2043::1]:50773
控制台中输入命令 lldb
时,它可以正常工作:
$ lldb
(lldb) process connect connect://[fd42:af35:2043::1]:50773
(lldb) process launch
问题
知道为什么 lldb 在尝试从“外部”发出执行的命令时挂起吗?还有其他可能将命令注入 lldb 吗?
其他命令如
script lldb.target.module[0].SetPlatformFileSpec(lldb.SBFileSpec('/private/var/containers/Bundle/Application/3DFF7807-330C-4A5E-8952-D93034FEC2AF/Test.app'))
使用“-o”选项。
这是一个错误,但是一个相当微妙的错误......
lldb的命令行可以以两种模式运行,“同步”和“异步”。在同步模式下,任何运行(或生成)lldb 正在调试的进程的命令都不会返回,直到该进程停止。该模式对于脚本来说很方便 - 包括您根据 lldb 的
-o
标志构建的启动脚本。
例如,如果您这样做:
$ lldb abinary -o "break set -n main" -o run -o bt
您希望
run
在运行 bt
命令之前停止在 main 的断点处。
在异步模式下,所有命令都会立即返回,然后 lldb 驱动程序异步等待停止并通知您。这是使用控制台的更方便的模式,因此 lldb 将尽可能以这种方式运行。如果 lldb 和正在调试的进程共享一个终端,则不可能执行此操作,但否则这就是 lldb 的运行方式。
该错误的第二个因素是
process connect
也存在歧义。另一端的存根可能已经有也可能没有它正在控制的进程。在达尔文,这就是跑步的区别:
$ debugserver localhost:12345
这是一个调试服务器,您可以连接到它并指示启动任何进程,并且:
$ debugserver localhost:12345 process_name
其中调试服务器使用二进制文件
process_name
启动一个进程并等待客户端附加到它。您可以添加更多参数来设置传递给新进程的参数和环境。
错误在于,在同步模式下,lldb 假设
process connect
将生成一个进程,并且它正在同步等待该进程。在异步模式下,如果它成功连接,然后检测到存根没有管理进程,它会在此时退出命令,将控制权返回给用户,以便他们可以执行process launch
。
如果您已连接到使用进程运行的调试服务器,则
process connect
将完成,并且您将留在命令行中,新进程处于停止状态。
这个事实为您提供了一种解决方法,如果您可以使用进程运行存根而不是让 lldb“启动”它。请注意,debugserver(和 lldb-server)会在新进程有机会执行任何代码之前停止它,因此您不会错过任何程序代码。从 lldb 启动的主要优点是易于设置参数和环境变量。
另一个解决方法是切换到
process connect
命令的异步模式,例如:
$ lldb -o "script old_debug = lldb.debugger.GetAsync()" -o "script lldb.debugger.SetAsync(True)" -o "gdb-remote localhost:12345" -o "script lldb.debugger.SetAsync(old_debug)"
后者输入起来会非常乏味,但您也可以将其放在命令文件中的某个位置并使用
-s
而不是 -o
。
如果您想提交有关此问题的错误,请使用 lldb 问题跟踪器: