Как скрыть сторонние вызовы в стеке вызовов в Xcode - PullRequest
8 голосов
/ 10 июля 2020

Когда я работаю с Realm или RxSwift и есть исключение, я получаю эти гигантские стеки вызовов, которые меня не волнуют, и мне нужно найти одну или две строки, которые являются моим кодом. Я хотел бы отображать только символы в стеке вызовов, которые находятся в целевой запущенной, а не связанных библиотеках. Как их скрыть?

введите описание изображения здесь

1 Ответ

16 голосов
/ 12 июля 2020

Я не знаю способа отфильтровать то, что отображает Xcode, но вы можете найти сценарий lldb python полезным. Существует как минимум три возможных способа фильтрации стека:

  1. Имя фрейма
  2. Библиотека
  3. Исходный путь

Во-первых, чтобы фильтровать стек по имени, можно использовать регулярное выражение для проверки имени функции. Регулярное выражение может соответствовать кадрам, которые вы хотите удалить, или тем, что вы хотите сохранить. Из данной трассировки стека я не могу сказать, какие из них вы хотите сохранить, поэтому я продемонстрирую удаление кадров Realm:

(lldb) script
import re
for frame in lldb.thread:
    if not re.search("[Rr]ealm|RLM", frame.name):
        print(f"{frame.idx}: {frame.name}")

Сопоставление по имени функции не всегда идеально, это может быть длинным или сложное регулярное выражение. Если библиотеки, которые вы хотите отфильтровать, являются динамическими c библиотеками или фреймворками, то самый простой способ - отфильтровать по «модулю»:

(lldb) script
for frame in lldb.thread:
    if frame.module.file.basename != "Realm":
        print(f"{frame.idx}: {frame.name}")

Третий вариант - фильтр по пути к источнику, связанному с каждым кадром. Я не знаю, что это сработает для Realm (это зависит от информации отладки), но я сделал это с помощью RxSwift. В этом примере кадры, в исходном пути которых указано RxSwift/, не будут напечатаны:

(lldb) script
for frame in lldb.thread:
    if "RxSwift/" not in frame.line_entry.file.fullpath:
        print(f"{frame.idx}: {frame.name}")

Команда многократного использования

Эти методы можно объединить, чтобы создать команду трассировки стека, которая подходит для ваш проект. Чтобы выполнить эту команду, поместите свой собственный for l oop в файл и загрузите его из своего ~/.lldbinit:

command script import path/to/mystack.py

При написании команды lldb необходимо внести несколько изменений . Вот пример, который объединяет два из вышеперечисленных методов:

import lldb
import re

REALM_PATTERN = re.compile("[Rr]ealm|RLM")

@lldb.command()
def mystack(debugger, command, ctx, result, _):
    for frame in ctx.thread:
        if not is_rx(frame) and not is_realm(frame):
            print(f"{frame.idx}: {frame.name}", file=result)

def is_realm(frame):
   return REALM_PATTERN.search(frame.name)

def is_rx(frame):
   return "RxSwift/" in frame.line_entry.file.fullpath
...