URLSession dataTask символическая точка останова на конкретном URL

У меня есть API-оболочка, которая регистрирует все URL, запрошенные URLSession, Мне нужно установить точку останова на конкретный URL-вызов, чтобы можно было легко найти место в пользовательском интерфейсе, откуда инициализируется вызов API.

Нет проблем остановиться на любой задаче URLSession. Я делаю это с lldb команда br set -F '-[__NSCFURLSessionTask resume]':

Добавление символической точки останова

Затем программа останавливается:

Итак, вопрос:

Есть ли способ получить URL из контекста на скриншоте выше, сопоставить его с предоставленным URL и продолжить, если URL не совпадает?

Или, может быть, некоторые другие идеи (lldb скрипт на питоне например)?

1 ответ

Решение

Давайте начнем с выяснения instance значениеуказателя в точке останова. С Objective-Cselector отправляется внутри Swift.resume() вызов мы должны вернуться к фактической реализации:

objc_msgSend(receiver, selector, arg1, arg2, ...)

Не вдаваясь в подробности, мы полагаемся на MacOS/iOS ABI, определяющий, какие регистры процессора используются для передачи аргументов. Нас особенно интересует первый аргумент, чтобы найти receiver instance значениеуказателя

Частный класс __NSCFURLSessionTask случается, имеет следующий метод:

- (NSURL*)currentRequest_URL;

@JimIngham указал на удивительный способ сделать это с помощью синонимов универсальных аргументов. $arg1 $arg2 ... в lldb, (обратите внимание, что селектор arg1 arg2 было бы lldb"s $arg3 $arg4 соответственно) Это упрощает это до:

po [$arg1 currentRequest_URL] 
https://www.google.com

В случае x8632bitSimulator что будет соответствовать устройствам ниже, чем iPhone 5S вы бы использовали вместо этого:

(lldb) x/x $esp+4
     0xbff9e050: 0x7874dd70
(lldb) po [0x7874dd70 currentRequest_URL]
    https://www.google.com
Другие вопросы по тегам