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.

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

6 ответов

Решение

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

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

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

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

dwarfdump --all kidsapp.app.dSYM

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

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

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

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) main

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

... остальная часть свалки

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

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

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

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

Было доведено до моего сведения, что load address действительно адрес двоичного файла mach-o. Хотя то, что я описал выше, часто может работать - это не совсем правильно. Это может быть получено с помощью CRASH REPORT, однако цель этого ответа состояла в том, чтобы предоставить символы сбоя, когда у вас нет отчета о сбое. Лучший способ, которым я пришел к выяснению 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 и armv7s.

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

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

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

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.

Итак, мой случай: я получаю строки сбоя из 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 из вашего архива в Организаторе не будут совпадать. введите описание изображения здесь

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

#!/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). Если невозможно запустить sctipt (./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

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

https://github.com/IdoTene/MacosSymbolicateCrash

Я думаю, что этот пост может помочь вам, /questions/47685671/sboj-simvolnogo-sboya-na-xcode-45/47685685#47685685. Коммит Джо подошел к моей проблеме.

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

Другие вопросы по тегам