atos и dwarfdump не будут символизировать мой адрес

Я получил отчет о сбое через AirBrake.io, который не символизируется. Поскольку отчет о сбое имеет не совсем тот же формат, что и журнал сбоев Apple, я не могу просто поместить его в XCode, как обычно, поэтому я взял точно такую ​​​​же сборку из своего архива XCode и попытался символизировать ее в командной строке. Со следующим результатом:

$ atos -o kidsapp.app/kidsapp 0x0002fc4c
0x0002fc4c (in kidsapp)

Я абсолютно уверен, что использую ту же сборку, что и отчет о сбое. Поэтому я также пробовал с dwarfdump:

$ dwarfdump --lookup 0x0002fc4c --arch armv7 kidsapp.app.dSYM
----------------------------------------------------------------------
 File: kidsapp.app.dSYM/Contents/Resources/DWARF/kidsapp (armv7)
----------------------------------------------------------------------
Looking up address: 0x000000000002fc4c in .debug_info... not found.
Looking up address: 0x000000000002fc4c in .debug_frame... not found.

Тоже никакого результата. Есть ли что-то еще, кроме использования неправильного файла dSYM, что я могу сделать неправильно? Я знаю, что это правильный вариант, поскольку эта версия упоминается в отчете о сбое в AirBrake и находится в моем архиве XCode.

Любые идеи/советы приветствуются!


person Mac_Cain13    schedule 20.04.2012    source источник


Ответы (6)


Прежде всего проверьте, действительно ли dSYM подходит для этого приложения:

dwarfdump --uuid kidsapp.app/kidsapp
dwarfdump --uuid kidsapp.app.dSYM

Оба должны вернуть один и тот же результат.

Затем проверьте, имеет ли dSYM какой-либо допустимый контент.

dwarfdump --all kidsapp.app.dSYM

Это должно дать хоть какую-то информацию, кроме not found.

Я предполагаю, что dSYM поврежден. В общем, вы можете использовать средство создания отчетов о сбоях, которое дает вам полный отчет о сбоях со всеми потоками и информацией о трассировке последнего исключения. Я рекомендую использовать что-то на основе PLCrashReporter, например. QuincyKit (SDK с открытым исходным кодом + сервер + символизация на вашем Mac) или HockeyApp (SDK с открытым исходным кодом + платная услуга + символизация на стороне сервера) (Примечание: я являюсь одним из разработчиков обоих!)

person Kerni    schedule 23.04.2012
comment
У меня такая же проблема. У меня есть отчет о сбое, который предоставляет трассировку стека, но ни один из символов из моего проекта, которые попадают в стек, не может быть найден в dSYM моего архива. UUID совпадают, но все символы отключены. Как это возможно и как я могу это решить? Apple как-то изменяет двоичный файл перед выпуском в магазин приложений, тем самым нарушая выравнивание с моим dSYM? - person NSProgrammer; 17.09.2012
comment
Вам нужно будет принять во внимание слайд двоичного файла и начальный адрес приложения. Вы не можете просто использовать адрес памяти из трассировки стека. Просто используйте скрипт symbolicatecrash из Xcode, который делает все, что вам нужно. - person Kerni; 17.09.2012
comment
Но если все, что у меня есть, это символы (я должен был сказать дамп стека, а не трассировка), который дает мне чисто шестнадцатеричные значения, как мне учитывать слайд? - person NSProgrammer; 17.09.2012
comment
адрес для использования с atos = slide + stack address - binary load address. Вы получаете слайд с dwarfdump из dsym или бинарника, проверьте, как это делает скрипт symbolicatecrash. адрес двоичной загрузки, который вы получаете из раздела двоичных изображений в отчете о сбое. - person Kerni; 18.09.2012
comment
Я ответил на свою конкретную подзадачу. - person NSProgrammer; 18.09.2012
comment
На первом этапе для первой строки возвращается архитектура armv7, а для второй (dSYM) — armv7s. Это проблема? - person sooper; 14.11.2013
comment
Нет, это не проблема, и это может произойти, если приложение имеет только срез armv7 в двоичном файле, но в системе есть не armv7, а armv7 (например, iPhone 5S). - person Kerni; 15.11.2013

Я использовал следующую арифметику, чтобы понять это:

slide + stack address - load address = symbol address

и

stack address - это шестнадцатеричное значение, которое я получаю из отчета о сбое дампа стека (не файл .crash, а просто дамп стека).

и

slide — это vmaddr команды LC_SEGMENT при запуске otool -arch armv7 -l APP_BINARY_PATH. Мой обычно заканчивается 0x00001000.

и

load address сложная штука. На самом деле это разница между самым нижним адресом стека основного потока и ПЕРВЫМ адресом той части моего двоичного файла, которая содержит символы при запуске dwarfdump --arch armv7 --all DSYM_BINARY_PATH. Это просто символический адрес функции main. Итак, если ваш самый нижний адрес сбоя — 0x8000, а символический адрес вашей основной функции — 0x2000, тогда ваш load address равен 0x6000.

Теперь со ВСЕМИ этими частями я могу вычислить адрес символа и поместить его в atos или dwarfdump: dwarfdump --lookup SYM_ADDR --arch armv7 APP_BINARY_PATH.

Пример дампа (вы можете видеть, что load address был 0x00003af4):

----------------------------------------------------------------------

Файл: /Users/user/Desktop/MyApp.xcarchive/dSYMs/MyApp.app.dSYM/Contents/Resources/DWARF/MyApp (armv7)

----------------------------------------------------------------------

0x00000024: [0x00003af4 - 0x00003b4e) основной

0x00000098: [0x00003b50 - 0x00003d8c) -[приложение MyAppDelegate: didFinishLaunchingWithOptions:]

... остальная часть дампа

Сложнее всего было понять, что в одной из двух статических библиотек, которые я включил, были удалены символы, прежде чем они стали ссылкой на двоичный файл моего приложения! Это оставило ОГРОМНЫЙ разрыв адресов символов, поэтому я получил только две трети символов, которые мне нужны, в моем dSYM.

Убедитесь, что следующие флаги установлены в NO в вашем проекте xcode статических библиотек, чтобы при компоновке с ним вы могли вставлять символы в двоичный файл вашего приложения (который позже можно удалить): COPY_PHASE_STRIP, DEAD_CODE_STRIPPING и STRIP_INSTALLED_PRODUCT.

Теперь вы можете спросить, что мне делать, если дамп стека не включает основную функцию, поскольку она не находится в основном потоке, поэтому я не могу получить адрес стека основной функции? На это я бы ответил, что понятия не имею! Просто скрестите пальцы и надейтесь, что вы сможете получить трассировку стека, включающую адрес символа, или использовать систему отчетов о сбоях, которая имитирует журналы сбоев Apple, например PLCrashReporter.

[РЕДАКТИРОВАТЬ 26 мая 2013 г.] -

Мое внимание было обращено на то, что load address на самом деле является адресом двоичного файла mach-o. Хотя то, что я описал выше, часто может работать - это не совсем правильно. Это можно получить с помощью ОТЧЕТА О АВАРИИ, однако смысл этого ответа заключался в том, чтобы предоставить символы сбоя, когда у вас нет отчета о сбое. Лучший способ, которым я пришел к выяснению load address, когда хочу символизировать, - это убедиться, что я регистрирую load address с stack addresses.

Я лично создал систему для регистрации сбоев (не отчетов о сбоях) и отправки их в корзину S3, откуда я могу получить их позже для отладки. Когда я запускаю свое приложение, я кэширую slide, load address и main function address для использования в случае сбоя моего приложения и отправляю stack addresses.

ПРИМЕЧАНИЕ: функции dyld используют #include <mach-o/dyld.h>

slide = адрес, возвращенный _dyld_get_image_vmaddr_slide(0)

load address = адрес, возвращенный _dyld_get_image_header(0)

main function address = последний адрес в [NSThread callStackReturnAddresses] при вызове в основном потоке

Во время сбоя я обязательно зарегистрирую [NSThread callStackReturnAddresses] и [NSThread callStackSymbols], а также архитектуру, которую можно получить с помощью этого метода:

- (NSString*) arch
{
    NSString* arch =
#ifdef _ARM_ARCH_7
        @"armv7";
#elif defined (_ARM_ARCH_6)
        @"armv6";
#else
        nil;
#endif

    return arch;
}

Я пока не знаю, как отличить armv7 от armv7.

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

Я обновил natos для поддержки доставки load address вручную: https://github.com/NSProgrammer/natos

person NSProgrammer    schedule 17.09.2012
comment
Я создал инструмент командной строки для выполнения всей тяжелой работы. Просто нужно 1) путь xcarchive, 2) адрес стека символа основной функции, 3) адрес стека нужного символа, 4) интересующая архитектура. Он находится на github: github.com/nob1984/natos. - person NSProgrammer; 30.09.2012
comment
Хорошая запись, но, к сожалению, в ней есть серьезная ошибка: адрес загрузки НЕ соответствует тому, что вы написали. Адрес загрузки можно найти в разделе двоичных изображений отчета о сбое, и он является начальным адресом диапазона адресов соответствующего двоичного файла. - person Kerni; 21.11.2012
comment
Я использовал ваши инструменты, но как я могу получить _mainFunctionStackAddress? Я нашел адрес с помощью dwarfdump в моем файле dsym и использовал его, но результат, который он мне дает, был таким же, как и с объяснением atos, я все еще не могу найти правильное положение точки сбоя. - person Zhou; 27.11.2012
comment
@Zhou, инструмент был обновлен, чтобы принимать только адрес загрузки вместо расчета на основе адреса стека основной функции. - person NSProgrammer; 27.05.2013
comment
@NSProgrammer, я пробовал с natos, но это не дало мне нужной функции. - person Titus; 24.02.2014
comment
@NSProgrammer Спасибо! Этот инструмент хорошо работает для 32-битных сборок. Я только что отправил вам PR на github, который обеспечивает поддержку 64-битной архитектуры для этого инструмента. - person Anton Gaenko; 19.03.2015
comment
@AntonGaenko PR слил - person NSProgrammer; 19.03.2015

Для тех, у кого это определенное время не имеет значения для адреса загрузки, например:

Jan 14 11:02:39 Dennins-iPhone AppName[584] <Critical>: Stack Trace: (
    0   CoreFoundation                      0x2c3084b7 <redacted> + 150
    1   libobjc.A.dylib                     0x39abec8b objc_exception_throw + 38
    2   CoreFoundation                      0x2c21cc35 CFRunLoopRemoveTimer + 0
    3   AppName                             0x0005a7db AppName + 272347  

Я создал простой bash, чтобы помочь мне отладить:

#! /bin/bash
read -p "[Path] [App Name] [Stack Address] [Relative Address] " path appName runtimeAddress relativeAddress
loadAddress=`echo "obase=16;ibase=10;$((runtimeAddress-relativeAddress))" | bc`
atos -o $path/Payload/$appName.app/$appName -l $loadAddress $runtimeAddress -arch armv7

Он просто считывает путь к приложению, имя приложения, адрес времени выполнения и значение после сигнала «+» (десятичное значение), а затем находит значение для адреса загрузки для запуска команды atos.

person DenninDalke    schedule 14.01.2015
comment
большое спасибо! У меня есть трассировка стека без адреса загрузки, и ваш скрипт был единственным способом получить адрес загрузки из времени выполнения и относительных адресов. - person Roma; 18.12.2020

Итак, мой случай: я получаю строки сбоя из NSException.callStackSymbols.

Трассировка стека сбоя выглядит следующим образом:

2   AppName                               0x00000001006c75b4 AppName + 2356660\r3   AppName                               0x00000001004f5cfc AppName + 449788\r4   UIKit                               0x000000018c0a8968 \u003credacted\u003e + 108\r5   UIKit      0x000000018c0a9328 \u003credacted\u003e + 28\r6   UIKit                               0x000000018beea250 \u003credacted\u003e + 1320\r7   UIKit                               0x000000018beede98 \u003credacted\u003e + 188\r8   UIKit                               0x000000018bcb5820 \u003credacted\u003e + 116\r9   UIKit                               0x000000018bbdec88 \u003credacted\u003e + 760\r10  UIKit                               0x000000018bbde610 \u003credacted\u003e + 312\r11  UIKit                               0x000000018bbde31c \u003credacted\u003e + 296\r12  UIKit                               0x000000018bbde3bc \u003credacted\u003e + 456\r13  QuartzCore                          0x0000000185b93b7c \u003credacted\u003e + 284\r14  libdispatch.dylib                   0x00000001811a8a2c \u003credacted\u003e + 16\r15  libdispatch.dylib                   0x00000001811b5654 \u003credacted\u003e + 1012\r16  CoreFoundation                      0x0000000181851650 \u003credacted\u003e + 12\r17  CoreFoundation                      0x000000018184f1a8 \u003credacted\u003e + 2272\r18  CoreFoundation                      0x000000018176f488 CFRunLoopRunSpecific + 552\r19  GraphicsServices                    0x0000000183735020 GSEventRunModal + 100\r20  UIKit         0x000000018bc09cc0 UIApplicationMain + 236\r21  AppName                               0x000000010048f714 AppName + 30484\r22  libdyld.dylib 0x000000018120dfc0 \u003credacted\u003e + 4

Не включайте биткод, так как Apple может перекомпилировать ваш код, и dsym-файлы из вашего архива в Organizer не будут совпадать. введите здесь описание изображения

Запустите такой bash-скрипт:

#!/bin/bash
appName=AppName
runtimeAddress=0x00000001006c75b4
relativeAddress=2356660
loadAddress=`echo "obase=16;ibase=10;$((runtimeAddress-relativeAddress))" | bc`
atos -o $appName.app/$appName -l $loadAddress $runtimeAddress -arch arm64

Предполагая, что вы создали test.sh (коснитесь test.sh). Если невозможно запустить сценарий (./test.sh) из-за проблем с правами доступа: вызовите chmod +x test.sh Теперь ./test.sh должен работать. И сгенерировать результат.

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

Также можно обозначить файл сбоя, используя файл AppName.app.dSYM:

#!/bin/bash
appName=AppName
runtimeAddress=0x00000001006c75b4
relativeAddress=2356660
loadAddress=`echo "obase=16;ibase=10;$((runtimeAddress-relativeAddress))" | bc`
atos -o $appName.app.dSYM/Contents/Resources/DWARF/$appName -l $loadAddress $runtimeAddress -arch arm64
person Naloiko Eugene    schedule 11.04.2018

Я думаю, что этот пост может вам помочь, https://stackoverflow.com/a/12559150/1773317. Коммит Джо решил мою проблему.

Причина в том, что мои файлы .app и .dSYM не могут быть проиндексированы Spotlight, поэтому мой XCode не может правильно символизировать информацию о сбое.

person Omega.yue    schedule 10.03.2013

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

https://github.com/IdoTene/MacosSymbolicateCrash

person IdoT    schedule 11.02.2018