Альтернатива DTSendSignalFlag для идентификации ключевых событий в инструментах?

Раньше был хороший инструмент DTSendSignalFlag, часть инфраструктуры DTPerformanceSession, с помощью которого можно было программно вставлять флаги в инструменты (см. сравнение">Сравнение трассировки Xcode Instruments). Эта функция перестала работать в iOS 7.

Кому-нибудь удалось заставить DTSendSignalFlag работать в iOS 7? Сигнальные флаги — это (были ли?) полезный способ программно размещать флаги в Инструментах с помощью кода (действительно полезно при диагностике сложных приложений в Инструментах), но я не вижу свои программно созданные флаги в Инструментах при запуске на симуляторе iOS 7 ( но это работает, когда у меня есть сборка Xcode 5 для симулятора iOS 6).


person Rob    schedule 26.09.2013    source источник
comment
Я не могу найти ни упоминания об этом, ни замены, если она исчезла. Хотелось бы, чтобы что-то подобное работало.   -  person perezda    schedule 09.11.2014


Ответы (2)


Вместо использования флагов теперь мы можем использовать программно вставленные указатели, которые фиксируются в «Точках интереса» инструмента.

В iOS 13 и macOS 10.15 мы можем использовать os_signpost. Это показано в видео WWDC 2019 Начало работы с инструментами.

Например, в Свифте:

  • Импортируйте единую структуру ведения журналов:

    import os.log
    
  • Создайте OSLog для точек интереса:

    private let pointsOfInterest = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: .pointsOfInterest)
    
  • Если вы хотите начать диапазон точек интереса, вы можете .begin указать точку интереса:

    let id = OSSignpostID(log: pointsOfInterest)
    os_signpost(.begin, log: pointsOfInterest, name: "Download", signpostID: id, "Download %d", index)
    
  • Если вы хотите закончить диапазон точек интереса, вы можете .end сделать это:

    os_signpost(.end, log: pointsOfInterest, name: "Download", signpostID: id, "Download %d", index)
    
  • Если вас интересует не диапазон времени, а отдельный указатель, вы можете просто опубликовать .event:

    os_signpost(.event, log: pointsOfInterest, name: "Done", "All done")
    

Или в Objective-C:

  • Импортируйте унифицированную структуру указателей ведения журналов:

    @import os.signpost;
    
  • Создайте OSLog для точек интереса:

    os_log_t log = os_log_create("ViewController", OS_LOG_CATEGORY_POINTS_OF_INTEREST);
    
  • Если вы хотите начать диапазон точек интереса, вы можете .begin точку интереса:

    os_signpost_id_t identifier = os_signpost_id_generate(log);
    os_signpost_interval_begin(log, identifier, "Download", "Started %d", index);
    
  • Если вы хотите закончить диапазон точек интереса, вы можете .end сделать это:

    os_signpost_interval_end(log, identifier, "Download", "Finished %d", index);
    
  • Если вас интересует не диапазон времени, а отдельный указатель, вы можете просто опубликовать .event:

    os_signpost_event_emit(log, OS_SIGNPOST_ID_EXCLUSIVE, "Done");
    

В любом случае, инструмент «Точки интереса» теперь может графически представлять ряд операций загрузки и разбора (каждая очередь ограничена двумя одновременными операциями на очередь) в инструментах:

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

Обратите внимание, что значения name (в одном наборе я использовал имя Download, а в другом — Parse) хорошо разделены на разные плавательные дорожки в инструменте Points of Interest. И поскольку я использовал необязательные строки формата, я действительно могу видеть сообщения, в которых я могу четко соотнести каждую операцию загрузки и синтаксического анализа с конкретной задачей в моем приложении.

Выше я использовал необязательные параметры OSSignpostID, потому что у меня было несколько перекрывающихся диапазонов, и я хотел избежать путаницы при связывании конкретного .end с соответствующим .begin. Если вы либо не используете диапазоны точек интереса, либо у вас нет перекрывающихся диапазонов, вам технически не нужно использовать этот необязательный параметр, если невозможна двусмысленность. (Даже если вы используете эти идентификаторы указателей, убедитесь, что name связанных указателей .begin и .end также совпадают, иначе инструменты не будут идентифицировать их как начало и конец одного и того же диапазона точек интереса, даже с одним и тем же указателем. я бы.)

В любом случае, теперь, когда у вас есть инструмент «Точки интереса», заполненный информацией, вы можете дважды щелкнуть по диапазону, чтобы выбрать его, или трижды щелкнуть по нему, чтобы также установить диапазон проверки.


В iOS 10 и macOS 10.12 мы использовали kdebug_signpost. Это показано в видео WWDC 2016 Подробная трассировка системы.

Для тех процессов, которые занимают дискретное количество времени, мы можем использовать kdebug_signpost_start и kdebug_signpost_end. Например:

kdebug_signpost_start(SignPostCode.download.rawValue, UInt(index), 0, 0, SignPostColor.orange.rawValue)
performDownload {
    kdebug_signpost_end(SignPostCode.download.rawValue, UInt(index), 0, 0, SignPostColor.orange.rawValue)
}

Чтобы отметить один момент времени, мы можем просто использовать kdebug_signpost:

kdebug_signpost(SignPostCode.done.rawValue, 0, 0, 0, SignPostColor.red.rawValue)

Первый параметр — это просто какой-то уникальный числовой код, соответствующий «кодовому имени указателя», который мы будем использовать в инструментах. Вы можете использовать любые значения (от 0 до 16383), но я использую то, что обозначает тип задачи:

enum SignPostCode: UInt32 {   // some custom constants that I'll reference in Instruments
    case download = 0
    case parse = 1
    case done = 2
}

Остальные параметры могут быть любыми значениями UInt, которые вы хотите, но в моем примере я буду использовать второй параметр в качестве уникального идентификатора для сопоставления повторяющихся вызовов start и end, а последний параметр я буду использовать для цветового кодирования своих регионов. в Инструменты:

enum SignPostColor: UInt {    // standard color scheme for signposts in Instruments
    case blue = 0
    case green = 1
    case purple = 2
    case orange = 3
    case red = 4
}

Сделав это, вы можете затем профилировать приложение в «Инструментах», нажать кнопку «+» в правой части панели инструментов «Инструменты» и добавить «Точки интереса». Настроив «Имена кодов указателей» так, чтобы они соответствовали числовым значениям, которые я передал в качестве первого параметра своим указателям, Instruments фактически переведет эти коды для меня. После того, как я профилирую приложение, мои интересы четко выделены:

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

На этом снимке я профилировал семь операций загрузки (оранжевым цветом) и семь операций синтаксического анализа (зеленым цветом), ограниченных двумя за раз соответственно. И когда они были готовы, я разместил единственный указатель «Готово» (красная булавка). Но детали этого демонстрационного приложения не имеют решающего значения, а скорее просто иллюстрируют, как отдельные указатели и указатели начала/конца отображаются в «Точках интереса» от Instruments.

Основная проблема в том, что теперь у меня есть четкое соответствие между событиями в моем коде и тем, что я вижу в Инструментах. И я могу управление-щелкнуть запись в списке диапазонов указателей и сказать инструментам "Установить фильтр времени", если я хочу, чтобы, когда я вернусь к другим моим инструментам (распределениям или времени профилировщик или что-то еще), диапазон проверки фильтруется до соответствующих точек интереса в моем приложении.


Обратите внимание, что это Swift. В Objective-C kdebug_signpost API похож, но вы должны включить:

#import <sys/kdebug_signpost.h>

Очевидно, то, как вы определяете свои перечисления для своих кодов, также изменится.

Обратите внимание, что этот kdebug_signpost API был представлен в iOS 10/macOS 10.12. Заголовки сообщают нам, что более ранние версии ОС могли использовать syscall:

В предыдущих версиях операционной системы приложения могли использовать:

syscall(SYS_kdebug_trace, APPSDBG_CODE(DBG_MACH_CHUD, <your event code>) | DBG_FUNC_<type>, arg1, arg2, arg3, arg4);

для записи событий, которые будут отображаться с помощью инструментов. syscall(2) теперь устарел, и этот интерфейс заменяет вышеуказанный вызов.

Примечание. Если вам придется использовать syscall в более ранней версии ОС, вам придется импортировать <sys/kdebug.h>:

#import <sys/kdebug.h>

Кроме того, я не смог найти объявление SYS_kdebug_trace ни в одном из заголовков, но наткнулся на ссылку в Интернете, в которой говорилось, что это значение равно 180, что я эмпирически проверил:

#ifndef SYS_kdebug_trace
#define SYS_kdebug_trace 180
#endif
person Rob    schedule 09.09.2016
comment
Есть ли способ сохранить/применить часто используемую конфигурацию вывески в Instruments (например, для помощи в отладке нескольких приложений, которые имеют общую кодовую базу)? Есть ли способ отслеживать события указателей напрямую с помощью dtrace (а не с помощью инструментов)? Отличный ответ, кстати! - person lilinjn; 08.10.2016
comment
@lilinjn - Использовать опцию «Сохранить как шаблон...» в меню «Файл» инструментов. Затем, в следующий раз, когда вы запустите Инструменты, вместо того, чтобы выбирать один из стандартных инструментов, нажмите «Пользовательский», и вы увидите там свой сохраненный шаблон. Re dtrace, я не знаю. - person Rob; 08.10.2016
comment
Для полноты -- я полагаю, что вы можете использовать способность dtrace отслеживать системные вызовы и их аргументы, а также небольшой реверс-инжиниринг, подразумеваемый устаревшей информацией о поддержке: syscall(SYS_kdebug_trace, APPSDBG_CODE(DBG_MACH_CHUD, <your event code>)... чтобы получить доступ к событиям указателей без инструментов (но я еще не проработал детали). Надеюсь, эти две дополнительные части информации сделают отличный ответ еще лучше. Спасибо! - person lilinjn; 08.10.2016
comment
Любые идеи о том, как избежать «конфликтов» в кодах singpost между несколькими библиотеками, которые все используют указатели? - person JanR; 21.02.2017
comment
@ Black_Ivory_86 - Здесь вы явно ограничены, но если это противоречит вашим кодам, вам просто нужно изменить используемые значения. Обратите внимание, что если ваша проблема связана с начальными/конечными указателями, вы можете свести к минимуму ошибки несовпадения начальных/конечных указателей, перейдя к параметрам точек интереса, которые позволяют указать, сопоставляете ли вы указатели просто по коду или по коду и первому. аргумент или по коду и потоку. - person Rob; 29.03.2017
comment
Я не могу заставить работать версию до-Sierra, использующую системный вызов, возможно, потому, что инструменты до-Sierra, которые я использую, не имеют точек интереса. - person JWWalker; 08.07.2017
comment
@JWWalker - я не думаю, что видео WWDC пошло бы по пути рассказа о том, как это сделать до Сьерры (и даже упоминания, если я правильно помню, что мы могли делать это в течение долгого времени) если бы не было способа запечатлеть их и в этой среде. Может быть, в каком-то другом инструменте, если не в точках интереса. Но у меня нет машины до Sierra, поэтому я не могу это подтвердить. Возможно, вам следует опубликовать свой вопрос либо на S.O. или на собственных дискуссионных форумах Apple. - person Rob; 08.07.2017
comment
Работал хорошо. Одна вещь, которая кажется упущенной в ответе, заключается в том, что вам нужна эта строка #import для использования этих функций: #import ‹sys/kdebug_signpost.h› - person Hiroshi Ichikawa; 29.03.2018
comment
Да, я заметил это, когда делал график точек интереса в ответ на вопрос Objective-C. Я обновил свой ответ выше соответственно. - person Rob; 29.03.2018
comment
Спасибо, Роб! Я не вижу интервалы указателей в инструменте Points of Interest, но мне нужно добавить инструмент os_signpost (нажмите кнопку + вверху справа). Однако я не вижу событий-указателей. - person fzwo; 25.03.2020
comment
Для тех, у кого возникли проблемы с поиском вариантов Objective-C, вот хорошая статья от хороших людей из PSPDFKit с кодом Swift и ObjC: pspdfkit.com/blog/2018/ - person fzwo; 25.03.2020
comment
В Xcode 11.4 указатели и области в точках интереса не создавались для целей симулятора iOS. Это снова исправлено в Xcode 11.4.1. - person Rob; 21.04.2020
comment
Могу ли я управлять цветами в новом API? Я действительно скучаю по этому... Я знаю, что он группирует для меня, но я не могу динамически назначать имена групп - что это за отсталый API... - person Paulius Liekis; 23.12.2020
comment
@PauliusLiekis - насколько мне известно, новый API не предоставляет этот четвертый параметр, который раньше использовался для цветового кодирования. Теоретически вы можете просто использовать API kdebug и потерять дорожки, но получить окраску и игнорировать/подавлять предупреждения об устаревании. Но это только краткосрочное решение. - person Rob; 24.12.2020
comment
@PauliusLiekis Вы также можете написать свой собственный инструмент и использовать разработку концепций событий. Введите для управления цветом (либо путем ссылки на явные имена цветов, либо на семантические значения «концепции событий». См. stackoverflow.com/a Например, /67852179/1271826 (в котором я диагностировал особую идиосинкразическую особенность пользовательских инструментов). дорожки становится довольно простым. - person Rob; 07.06.2021