10

我的软件使用 SIGUSR2 信号,我使用 LLDB(在 Xcode 4.6.2 下)作为调试器。我想禁止 LLDB 在 SIGUSR2 停止,并且一直在使用以下命令:

process handle --pass true --stop false --notify true SIGUSR2

我正在寻找一种让 LLDB 在启动时始终执行此命令的方法。我已经考虑settings append target.process.extra-startup-command process在我的 .lldbinit 中添加一些内容,但是虽然这会改变 target.process.extra-startup-command 设置的值(如命令所证明的那样settings show),但我不确定是否/如何使用此设置始终执行process handle禁用 SIGUSR2 信号的命令。

我知道此处发布的“解决方案”:Permanently configure LLDB (in Xcode 4.3.2) not stop on signals。但是,如果存在,我正在寻找更优雅的解决方案。

4

3 回答 3

6

目前,在断点命令中执行此操作的建议main是可用的最优雅的解决方案。

gdb 有这样的世界观,所有的进程,无论它们在什么系统上,都会神奇地响应 UNIX 信号。所以说当进程得到一个 SIGINT 时会发生什么是有道理的,比如说,在你有一个进程之前。在 lldb 中,进程在创建时会告诉我们它的信号是什么以及它们的默认行为。这很可爱,只是这意味着现在没有自然的地方可以在您拥有进程之前存储信号行为的配置选项。这只是必须添加的东西。

触发“进程生命周期事件”的能力,不仅仅是“进程启动”,还有“进程退出”和“共享库加载”等,将是一个很好的补充。提交增强请求 ( http://bugreport.apple.com/ ) 会非常适合此功能,因为像这样的错误可以作为对功能的投票。

顺便说一句,target.process.extra-startup-command做一些完全不同的事情。它允许您在我们开始运行之前将一些命令添加到 lldb 发送到其调试代理(例如调试服务器)的序列中。它的主要用途是打开更多的调试服务器日志记录。

于 2013-06-07T22:00:23.777 回答
5

由于我经常回到这个问题来配置它,我最终创建了一个小脚本来自动完成:

import lldb
import threading

class ProcessEventListener(threading.Thread):
    def __init__(self, debugger):
        super(ProcessEventListener, self).__init__()
        self._listener = debugger.GetListener()
        self._debugger = debugger
        self._interpreter = debugger.GetCommandInterpreter()
        self._handled = set()

    def _suppress_signals(self, process):
        signals = process.GetUnixSignals()
        signals.SetShouldStop(11, False)

    def run(self):
        while True:
            event = lldb.SBEvent()
            if not self._listener.PeekAtNextEvent(event):
                continue                
            process = self._interpreter.GetProcess()
            if process and not process.GetUniqueID() in self._handled:
                self._suppress_signals(process)
                self._handled.add(process.GetUniqueID())

def __lldb_init_module(debugger, *rest):
    listener_thread = ProcessEventListener(debugger)
    listener_thread.start()

要使用,请将其放在类似的位置ignore_signals.py并从以下位置引用它.lldbinit

command script import ~/ignore_signals.py

我怀疑这可以进一步改进,所以我也把它放在了GitHub 上,以防有人愿意贡献。

于 2019-08-31T14:34:19.500 回答
0

受到rwestberg's answer 的启发,我能够编写一个不消耗 100% CPU 的类似脚本。在rwestberg的脚本中,这是必要的,因为脚本试图在 lldb 本身将事件从侦听器中永久删除之前从侦听器中读取事件。

这是改进的脚本:

import lldb
import threading
import time

class UnixSignalDisabler(threading.Thread):
    def __init__(self, debugger):
        super(UnixSignalDisabler, self).__init__()
        self._debugger = debugger
        self._handled = set()

    def _suppress_signals(self, process):
        print("UnixSignalDisabler: disabling SIGBUS, SIGSEGV in process #" + str(process.GetUniqueID()))
        signals = process.GetUnixSignals()
        signals.SetShouldStop(10, False) # SIGBUS
        signals.SetShouldStop(11, False) # SIGSEGV

    def run(self):
        while True:
            for target in self._debugger:
                if target:
                    process = target.GetProcess()
                    if process and not process.GetUniqueID() in self._handled:
                        self._suppress_signals(process)
                        self._handled.add(process.GetUniqueID())
            # Don't hog CPU
            time.sleep(0.03)

def __lldb_init_module(debugger, *rest):
    # Can't use 'debugger' reference directly because it gets deleted after calling '__lldb_init_module'
    debugger = lldb.SBDebugger.FindDebuggerWithID(debugger.GetID())
    listener_thread = UnixSignalDisabler(debugger)
    listener_thread.start()

要使用,请将其放在类似的位置ignore_signals.py并从以下位置引用它.lldbinit

command script import ~/ignore_signals.py
于 2021-12-11T04:37:46.050 回答