ݺߣ

ݺߣShare a Scribd company logo
Николай Волосатов — Работа с крэшами библиотек
Работа с крэшами библиотек
Николай Волосатов
〉Что такое крэш?
〉Как его поймать?
〉Как понять, что упала библиотека?
〉Как мы сделали это в AppMetrica?
3
О чём этот доклад?
4
AppMetrica
5
Что такое крэш?
6
Отчеты о крэшах в iOS
Как понять причину крэша в iOS?
7
Отчеты о крэшах в iOS
8
Отчеты о крэшах в iOS
AppMetrica
iTunes Connect
9
Отчеты о крэшах в iOS
10
Отчеты о крэшах в iOS
11
Отчеты о крэшах в iOS
AppMetrica
12
Отчеты о крэшах в iOS
Fatal system signal
C++ exception
Objective-C exception
Crash
13
Информация в отчете
Incident Identifier: F8DF04B0-3AA5-49FA-BD35-4606C376FC7D
CrashReporter Key: 17b3b8e83c9444a052974e768708c8a1434cb680
Hardware Model: iPhone5,1
Process: AppExecutable [2794]
Path: /var/containers/.../AppExecutable
Version: 1.0.0 (120)
Code Type: ARM
Parent Process: unknown [1]
Date/Time: 2016-08-06 16:25:07.000 +0300
OS Version: iPhone OS 9.3.2 (13F69)
Report Version: 104
14
Информация в отчете
Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: 0x00000000 at 0x23293c5c
Crashed Thread: 0
15
Информация в отчете
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x00000001877a00a0 0x187780000 + 131232 (objc_retain + 16)
1 UIKit 0x000000018ec87e30 0x18eb1a000 + 1498672 (<redacted> + 64)
2 AppExecutable 0x00000001000aba98 0x100058000 + 342680 (-[MyClass doCrash] + 276)
3 UIKit 0x000000018eb4193c 0x18eb1a000 + 162108 (<redacted> + 624)
4 UIKit 0x000000018eb416b4 0x18eb1a000 + 161460 (<redacted> + 156)
5 CoreFoundation 0x0000000188c2a048 0x188c21000 + 36936 (CFRunLoopRunSpecific + 444)
6 GraphicsServices 0x000000018a6ab198 0x18a69f000 + 49560 (GSEventRunModal + 180)
7 UIKit 0x000000018eb8f908 0x18eb1a000 + 481544 (UIApplicationMain + 208)
8 AppExecutable 0x00000001000d6fd8 0x100058000 + 520152 (main + 80)
9 libdyld.dylib 0x0000000187c0c5b8 0x187c08000 + 17848 (<redacted> + 4)
16
Информация в отчете
AppExecutable 0x00000001000aba98 0x100058000 + 342680 (-[MyClass doCrash] + 276)
AppExecutable - Имя файла исполняемого модуля
0x00000001000aba98 - Абсолютный адрес инструкции в памяти
0x100058000 - Адрес исполняемого модуля
342680 - Смещение инструкции относительно базового адреса исполняемого модуля
-[MyClass doCrash] - Имя символа(метода и класса), содержащего данную инструкцию
276 - Смещение инструкции относительно базового адреса символа
17
Информация в отчете
0x00000001000aba98
AppExecutable 0x100058000
-[MyClass doCrash]
276 bytes
342680 bytes
0x00000001000aba98
AppExecutable 0x00000001000aba98 0x100058000 + 342680 (-[MyClass doCrash] + 276)
18
Определение крэша библиотеки
19
Определение крэша библиотеки
1. Выделить все методы библиотеки
2. Проверить их наличие в упавшем потоке
3. ???
4. PROFIT
20
Определение крэша библиотеки
Динамические фреймворки
iOS 8+
MyFramework 0x00000001000c35efa 0x185186000 + 5671 (-[MyClass doCrash] + 179)
21
Определение крэша библиотеки
Статические фреймворки и библиотеки "из исходников"
AppExecutable 0x00000001000aba98 0x100058000 + 342680 (-[MyClass doCrash] + 276)
22
Определение крэша библиотеки
Symbols Stripping
AppExecutable 0x00000001000aba98 0x100058000 + 342680 (-[MyClass doCrash] + 276)
AppExecutable 0x00000001000aba98 0x100058000 + 342680 (_mh_execute_header + 342680)
+ dSYM
Debug Symbols
Не позволяет определять методы библиотеки по имени
23
Информация в отчете
0x00000001000aba98
AppExecutable 0x100058000
-[MyClass doCrash]
276 bytes
342680 bytes
0x00000001000aba98
AppExecutable 0x00000001000aba98 0x100058000 + 342680 (-[MyClass doCrash] + 276)
24
Информация в отчете
0x00000001000aba98
AppExecutable 0x100058000
_mh_execute_header
342680 bytes
342680 bytes
0x00000001000aba98
AppExecutable 0x00000001000aba98 0x100058000 + 342680 (_mh_execute_header + 342680)
25
Рантайм ObjectiveC
-[MyClass doCrash] 0x00000001000AB984
-[MyClass doCrash] 0x00000001000AB984
-[MyClass doCrash] 0x00000001000ABA98
адрес метода
адрес метода
адрес инструкцииметод
метод
метод
26
Определение крэша библиотеки в AppMetrica
Как мы делаем это в AppMetrica?
27
Определение крэша библиотеки в AppMetrica
Как выделить все адреса методов библиотеки?
.... App SDK SDK App App App SDK App ....
Память инструкций
Замечания
1. Методы одного класса располагаются в памяти последовательно
2. Категории могут располагаться далеко от их классов
3. Классы отсортированы в алфавитном порядке
28
Определение крэша библиотеки в AppMetrica
Определение метода по адресу инструкции в памяти
1. Получить адреса всех методов.
2. Все методы одного класса располагаются друг за другом.
3. Все адреса между адресами двух методов являются адресами инструкций первого.
Точный способ
29
Определение крэша библиотеки в AppMetrica
Определение метода по адресу инструкции в памяти
Точный способ
Наш классЧужой класс Чужой класс
Наши методы
!
30
Определение крэша библиотеки в AppMetrica
Определение метода по адресу инструкции в памяти
1. Получить адреса только интересующих нас методов.
2. Все методы одного класса располагаются друг за другом.
3. Все адреса между адресами двух методов являются адресами инструкций первого.
4. Будем считать размер последнего метода класса равным 1 байту.
Быстрый способ
31
Определение крэша библиотеки в AppMetrica
Определение метода по адресу инструкции в памяти
Наш классЧужой класс Чужой класс
Наши методы
! ? ? ?
Быстрый способ
32
Определение крэша библиотеки в AppMetrica
Определение метода по адресу инструкции в памяти
Наш классЧужой класс Чужой класс
? ? ?
.cxx_destruct
при ARC, для объектов с полями-объектами
Быстрый способ
33
Рантайм ObjectiveC <objc/runtime.h>
Получить список всех классов
objc_copyClassList
/Class *arrayOfClasses/
34
Рантайм ObjectiveC <objc/runtime.h>
Для каждого класса получить список методов
class_copyMethodList
/Method *arrayOfMethods/
35
Рантайм ObjectiveC <objc/runtime.h>
Для метода получить его адрес в памяти
method_getImplementation
0x00000001000ab984
36
Рантайм ObjectiveC <objc/runtime.h>
Выяснить, является ли метод статическим
class_isMetaClass
NO
37
Рантайм ObjectiveC <objc/runtime.h>
Для метода получить его имя
method_getName + sel_getName
doCrash
38
Рантайм ObjectiveC <objc/runtime.h>
Для класса получить его имя
class_getName
MyClass
39
Рантайм ObjectiveC <mach-o/dyld.h>
Получить информацию о подключенных библиотеках
_dyld_image_count + _dyld_get_image_header(index) + ...
0x100058000 - 0x10cf0ffff
AppExecutable
armv7
<92e6f4a1c6da372b8cfa09dfce3aac9e>
/var/containers/Bundle/Application/.../AppExecutable
40
Определение крэша библиотеки в AppMetrica
Определение классов AppMetrica SDK по префиксу
YMM*
PodYandexMobileMetrica_*
41
Определение крэша библиотеки в AppMetrica
Бонус!
Символикация методов библиотеки на устройстве
42
Определение крэша библиотеки в AppMetrica
Сбор информации об адресах наших методов
Работа приложения
КРЭШ
только при первом запуске
Запуск приложения
Формирование отчета о крэше
Поиск инструкций, принадлежащих нашим методам
Частичная символикация наших методов
(!)
runtime
43
Определение крэша библиотеки в AppMetrica
Опасный код
+Флаг Транзакции (NSUserDefaults)Запуск ...
...-Флаг Транзакции
Crash-Safe-Transaction
44
Определение крэша библиотеки в AppMetrica
Опасный код
+Флаг Транзакции (NSUserDefaults)
КРЭШ
Запуск ...
...+Флаг ТранзакцииЗапуск ...
Опасный код
Crash-Safe-Transaction
45
Статистика за неделю
1318
крэш-логов
16
приложений
7
дней
47
уникальных крэшей
23
воспроизводимых крэша
〉 О крэшах в целом
〉 Способы определения причины крэша
〉 Способы определения крэша библиотеки
〉 Как мы делаем всё это в AppMetrica
46
Что было в этом докладе?
Николай Волосатов
Разработчик, Группа мобильных SDK
Контакты
@bamx23
bamx23bamx23@yandex-team.ru
Спасибо за внимание!
Вопросы?

More Related Content

Николай Волосатов — Работа с крэшами библиотек