Символизация трассировки стека без сбоя

Есть ли способ обозначить трассировку стека, которая не является полным отчетом о сбое?

Я регистрирую строковый результат [NSThread callStackSymbols] на нашем сервере. Это дает не полностью отформатированный отчет о сбоях, а только несимметричную трассировку стека (пример ниже).

Я попытался символизировать именно это. Я также попытался заменить трассировку стека потока 0 фактического отчета о сбое из той же сборки. Ни то, ни другое не сработало. У меня есть dSYM сборки в архиве приложения. Есть ли способ сделать это, не оставляя символов в сборке раздачи?

0   domino free                         0x00072891 domino free + 465041
1   domino free                         0x000ea205 domino free + 954885
2   domino free                         0x000ea033 domino free + 954419
3   domino free                         0x0007fe55 domino free + 519765
4   domino free                         0x0006f6d5 domino free + 452309
5   domino free                         0x0006f7a3 domino free + 452515
6   domino free                         0x0006fb9b domino free + 453531
7   Foundation                          0x30558c29 __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke_0 + 16
8   Foundation                          0x304b06d9 -[NSURLConnectionInternalConnection invokeForDelegate:] + 28
9   Foundation                          0x304b06a3 -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] + 198
10  Foundation                          0x304b05c5 -[NSURLConnectionInternal _withActiveConnectionAndDelegate:] + 60
11  CFNetwork                           0x31f297f5 _ZN19URLConnectionClient23_clientDidFinishLoadingEPNS_26ClientConnectionEventQueueE + 192
12  CFNetwork                           0x31f1e4a5 _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 424
13  CFNetwork                           0x31f1e599 _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 668
14  CFNetwork                           0x31f1e1a3 _ZN19URLConnectionClient13processEventsEv + 106
15  CFNetwork                           0x31f1e0d9 _ZN17MultiplexerSource7performEv + 156
16  CoreFoundation                      0x30abead3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
17  CoreFoundation                      0x30abe29f __CFRunLoopDoSources0 + 214
18  CoreFoundation                      0x30abd045 __CFRunLoopRun + 652
19  CoreFoundation                      0x30a404a5 CFRunLoopRunSpecific + 300
20  CoreFoundation                      0x30a4036d CFRunLoopRunInMode + 104
21  GraphicsServices                    0x30e7f439 GSEventRunModal + 136
22  UIKit                               0x3123acd5 UIApplicationMain + 1080
23  domino free                         0x0004fd3b domino free + 322875
24  domino free                         0x00004004 domino free + 12292

person jakeo    schedule 31.07.2012    source источник
comment
возможный дубликат символьных отчетов о сбоях приложения iPhone   -  person Ky Leggiero    schedule 28.07.2015
comment
Если у вас нет полного отчета о сбоях, вам нужно вычислить правильный адрес для atos. См. Ответ NSProgrammer на аналогичную тему: stackoverflow.com/a/12464678/4615232   -  person Kasia K.    schedule 23.11.2015


Ответы (3)


Я знаю, что это довольно старый вопрос, но сейчас у меня была такая же проблема, и потребовалось некоторое время, чтобы найти ответ, поэтому я подумал, что лучше задокументировать его (где-то).

Если у вас есть dSYM для той версии приложения, откуда берется трассировка стека, вы действительно можете превратить это во что-то полезное. Прочтение этого ответа здесь приведет к эта статья, которая мне очень помогла. У меня была эта строка поверх трассировки стека:

0    MyApp                           0x000000010010da68 MyApp + 236136
                                     ^ stack address            ^ symbol offset

У вас есть два варианта, оба связаны с математикой. Если вы выберете atos, вам просто нужно один раз сделать математику, и вы можете просмотреть все шаги с помощью одного вызова.

Использование atos

Чтобы использовать atos, вам нужен адрес стека из трассировки стека, и вам нужно узнать адрес загрузки с помощью некоторой математики:

  1. Рассчитайте значение адреса загрузки, вычтя значение смещения символа из значения адреса стека (load address = stack address - symbol offset), конечно, вам нужно преобразовать их на одну базу, чтобы сделать это

    В моем случае это было 0x1000D4000

  2. Найдите записи трассировки стека с помощью atos, используя адрес загрузки и адреса стека из трассировки стека с помощью atos -arch <architecture> -o <path to executable inside (!) the dSYM> -l <load address> <stack address 1> <stack address 2> ...

    В моем случае это было atos -arch arm64 -o MyApp.app.dSYM/Contents/Resources/DWARF/MyApp -l 0x1000D4000 0x000000010010da68

Имейте в виду, что вы должны указать путь к фактическому исполняемому файлу внутри dSYM, иначе вы получите только сообщение об ошибке. Хорошая вещь в том, чтобы делать все это с atos, заключается в том, что вы можете просто перечислить все адреса из трассировки стека, и вы сразу получите читаемый формат.

Использование dwarfdump

Для использования dwarfdump вам потребуется адрес файла, соответствующий адресу стека в трассировке стека.

  1. Узнайте значение слайда для архитектуры, откуда берется трассировка стека (см. Получение значения слайда в связанной статье).

    В моем случае это было 0x100000000 для 64-битной версии.

  2. Преобразуйте значение смещения символа (число сразу после MyApp + ... в трассировке стека, 236136 в моем случае) в шестнадцатеричное и добавьте результат в слайд. Номер, который вы получаете сейчас, называется адресом файла (file address = symbol offset + slide).

    В моем случае это привело к 0x100039A68.

  3. Найдите записи трассировки стека с помощью dwarfdump, используя адрес файла с dwarfdump --lookup <file address> --arch <architecture> <path to dSYM>

    В моем случае это было dwarfdump --lookup 0x100039A68 --arch arm64 MyApp.dSYM

person Peter Tutervai    schedule 20.09.2016
comment
Вот пример из файла .ips в формате 2019: 4 MyApp 0x0000000102dd0068 0x102db8000 + 98408, где 0x102db8000 - адрес загрузки, а 0x0000000102dd0068 - адрес готового к использованию стека. Особая благодарность за комментарий dSYM, это было неочевидно. - person Victor Sergienko; 18.06.2019
comment
atos one дает другое шестнадцатеричное значение - person Geetanshu Gulati; 04.06.2021

Я столкнулся с той же проблемой, и этот ответ сработал для меня: https://stackoverflow.com/a/4954949/299262

Вы можете использовать atos для обозначения отдельных адресов, если у вас есть dSYM.

пример команды:

atos -arch armv7 -o 'app name.app'/'app name' 0x000000000

person Ben Baron    schedule 28.09.2012
comment
В примере, приведенном выше, как найти адрес вашего процесса (заменив 0x000000000 адресом в памяти domino free)? - person Dov; 22.09.2015

Я не думаю, что это возможно. [NSThread callStackSymbols] возвращает адрес памяти функций. Это невозможно обозначить без сброса памяти сразу после сбоя. При сбое адреса у каждого устройства разные. Даже на одном устройстве при перезагрузке телефона адреса менялись после очередного сбоя. Несколько парней упомянули atos, но это для журнала сбоев, а не для callStackSymbols.

person dqshll    schedule 08.12.2015
comment
Это неправда, если у вас есть dSYM, вы действительно можете получить полезную информацию из трассировки стека. Просто нужно много гуглить, чтобы найти правильные ответы;) - person Peter Tutervai; 20.09.2016