2015-12-08 9 views
5

Цель:Как "вручную" symbolicate [NSThread callStackSymbols] (получить начальный адрес для Atos) (IOS)

Я хочу symbolicate на "выход" из [NSThread callStackSymbols].

Боковых Примечания:

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

Мне нужно запустить мои тесты на устройстве, поэтому я не могу использовать Симулятор.

Текущий подход:

Когда я называю это:

NSLog(@"call stack:\n%@", [NSThread callStackSymbols]); 

я получаю этот выход:

2015-12-08 15:04:03.888 Conversion[76776:4410388] call stack: 
(
    0 Conversion       0x000694b5 -[ViewController viewDidLoad] + 128 
    1 UIKit        0x27259f55 <redacted> + 1028 
    ... 
    9 UIKit        0x274f67a7 <redacted> + 134 
    10 FrontBoardServices     0x2b358ca5 <redacted> + 232 
    11 FrontBoardServices     0x2b358f91 <redacted> + 44 
    12 CoreFoundation      0x230e87c7 <redacted> + 14 
    ... 
    16 CoreFoundation      0x23038ecd CFRunLoopRunInMode + 108 
    17 UIKit        0x272c7607 <redacted> + 526 
    18 UIKit        0x272c22dd UIApplicationMain + 144 
    19 Conversion       0x000767b5 main + 108 
    20 libdyld.dylib      0x34f34873 <redacted> + 2 
) 

("Преобразование" в этом выводе приложение.)

Теперь я могу использовать эту команду, чтобы «символизировать» объявление платья:

xcrun atos -o /path/to/Conversion.app -arch arm64 -l 0x0??? 

Run так (конечно, с соответствующим значением для -l), можно вводить адреса как 0x000694b5 и выложит что-то вроде -[ViewController viewDidLoad] + 128. Конечно, проблема заключается в начальном адресе (значение опции -l).

Когда у меня есть журнал сбоев, я могу получить их. Однако я хотел бы уйти без крушения.

Вопросы:

Q1: Могу ли я определить начальный адрес во время выполнения и, возможно, включить его в выходной журнал, так что я могу кормить его к Atos -l вариант?

EDIT: Похоже, что это возможно, как это: (спасибо NSProgrammer ответа https://stackoverflow.com/a/12464678/1396265)

#import <mach-o/dyld.h> 

... 
intptr_t slide = _dyld_get_image_vmaddr_slide(0); 
const struct mach_header * load_addr = _dyld_get_image_header(0); 
NSLog(@"slide %lx load addr %lx", (long)slide, (long)load_addr); 

/EDIT

(как я заинтересован в вызове методы фреймворки, я, конечно, нужен начальные адреса фреймворков. Начальный адрес приложения часто изменяется (рандомизация), я еще не знаю, были ли рандомизированы начальные адреса каркаса.)

Q2: Существуют ли другие подходы к исследованию методов в стеке вызовов? (точки останова также довольно неуклюжи в моем сценарии.)

EDIT:

Q3: Как я могу symbolicate адреса рамок? Например, где я могу найти dSYM (или что-то еще) для UIKit?

(К примеру у меня есть что-то на:. ~/Library/Developer/Xcode/iOS\ DeviceSupport/9.1\ \(13B143\)/Symbols/System/Library/Frameworks/UIKit.framework/ я изучу более подробно здесь.)

/EDIT

Может быть, решение:

Одним из способов может быть, сохранить вывод журнала в файл, а в конце тестов вызвать сбой в приложении. Таким образом, в журнале сбоев будут отображаться начальные адреса и с информацией стека вызовов из журналов, которые я должен иметь возможность отображать вывод callStackSymbols. Я попробую это дальше.

+0

Есть несколько способов сделать это, если symbolicatecrash не работает, в том числе Atos, dwarfdump и lldb. Существует очень приятная запись о полном символическом процессе [здесь] (https://www.apteligent.com/developer-resources/symbolicating-an-ios-crash-report/?partner_code=GDC_so_symbolicateios), который может быть дополнительная помощь – cjbeauchamp

ответ

3

Добавление фрагментов журнала в журнал сбоев доработало до сих пор, поэтому я добавлю это как ответ на данный момент. (Better ответы, безусловно, приветствуется :-))

Препараты:

Добавить callStackSymbols лесосечного в соответствующих местах в исходном коде:

NSLog(@"call stack:\n%@", [NSThread callStackSymbols]); 

вылетает приложение (например, когда определенный экран открыт):

strcpy(0, "000"); 

Перенаправление вывода журналирования в файл:

FILE *logfile = freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr); 

Исполнение:

В Xcode запустить приложение один раз, так что он получает установлен на устройстве, а затем остановить его. Затем запустите приложение непосредственно на устройстве, поэтому Xcode не будет ловить краш.

Используйте приложение, чтобы стек вызовов был зарегистрирован (может быть много раз).

В конечном счете сделать авария приложения (в моем случае откройте определенный экран, который вызывает плохой strcpy).

Получение файлов:

В Xcode открыто «Окно -> Устройства» выберите устройство, выберите приложение и загрузить контейнер приложение, поэтому файл журнала может быть извлечена.

На этом же экране откройте журналы устройств и экспортируйте журнал сбоев.

В окне Xcode open «Window -> Projects» выберите проект и покажите папку с производными данными в Finder (маленькая стрелка справа от пути данных). В папке с производными данными перейдите к «Build/Products/Debug-iphoneos /» и скопируйте MyApp.app и MyApp.app.dSYM.

Настройте журнал сбоев:

Для меня он работал, чтобы добавить дополнительные секции резьбы перед «бинарными изображениями:». Поэтому найдите расположение «Двоичные изображения:». Вставьте строку «Thread 9999:». Скопируйте & вставьте стек вызовов отвалов и удалить ведущие пробельные колонки так, что это выглядит следующим образом:

2015-12-09 15:28:58.971 MyApp[21376:3050653] call tree (
Thread 9999: 
0 MyApp        0x00000001001d95f8 -[MyClass myMethod:] + 100 
1 UIKit        0x000000018a5fc2ac <redacted> + 172 
2 UIKit        0x000000018a5d5ca4 <redacted> + 88 
3 UIKit        0x000000018a5d5b8c <redacted> + 460 
4 UIKit        0x000000018a5d5cc0 <redacted> + 116 
5 UIKit        0x000000018a5d5b8c <redacted> + 460 
6 UIKit        0x000000018a5d5cc0 <redacted> + 116 
7 UIKit        0x000000018a5d5b8c <redacted> + 460 
8 UIKit        0x000000018a8e85ac <redacted> + 460 
9 UIKit        0x000000018a5d4abc <redacted> + 96 
10 UIKit        0x000000018a935b7c <redacted> + 344 
11 UIKit        0x000000018a9306f8 <redacted> + 124 
12 UIKit        0x000000018aa584d8 <redacted> + 44 
13 UIKit        0x000000018a933d9c <redacted> + 188 
14 UIKit        0x000000018a70b668 <redacted> + 116 
15 UIKit        0x000000018a70b454 <redacted> + 252 
16 UIKit        0x000000018a70af38 <redacted> + 1404 
17 UIKit        0x000000018a70a9a8 <redacted> + 124 
18 UIKit        0x000000018a616d3c <redacted> + 312 
19 UIKit        0x000000018a616bc4 <redacted> + 108 
20 QuartzCore       0x0000000189dddc2c <redacted> + 284 
21 libdispatch.dylib     0x000000019a3a96a8 <redacted> + 16 
22 libdispatch.dylib     0x000000019a3aedb0 _dispatch_main_queue_callback_4CF + 1844 
23 CoreFoundation      0x00000001850001f8 <redacted> + 12 
24 CoreFoundation      0x0000000184ffe060 <redacted> + 1628 
25 CoreFoundation      0x0000000184f2cca0 CFRunLoopRunSpecific + 384 
26 GraphicsServices     0x000000018ff94088 GSEventRunModal + 180 
27 UIKit        0x000000018a644ffc UIApplicationMain + 204 
28 MyApp        0x0000000100093918 main + 124 
29 libdyld.dylib      0x000000019a3da8b8 <redacted> + 4 

Binary Images: 
... 

«Тема 9999:» линия делает symbolicatecrash скрипт хочет symbolicate следующих строк. Я выбрал 9999, поэтому я знаю, что это были мои добавленные разделы.

Run symbolication:

Найти symbolicatecrash скрипт:

$ find /Applications/Xcode.app -name symbolicatecrash -type f 
/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash 
$ 

Команда symbolication идет почти так:

$ symbolicatecrash myapp.crash MyApp.app.dSYM > myapp-sym.crash 

Вам нужно установить DEVELOPER_DIR и предварять путь к сценарий, поэтому со временем это выглядит так:

$ DEVELOPER_DIR='/Applications/Xcode.app/Contents/Developer' /Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash myapp.crash MyApp.app.dSYM > myapp-sym.crash 

Или обернуты для лучшего качества просмотра:

$ DEVELOPER_DIR='/Applications/Xcode.app/Contents/Developer' ... 
/Applications/Xcode.app/Contents/SharedFrameworks/ ... 
DTDeviceKitBase.framework/Versions/A/Resources/ ... 
symbolicatecrash myapp.crash MyApp.app.dSYM > myapp-sym.crash 

Результат:

В symbolicated сниппеты выглядеть следующим образом:

2015-12-09 15:28:58.971 MyApp[21376:3050653] call tree (
Thread 9999: 
0 MyApp        0x00000001001d95f8 -[MyClass myMethod:] (MyFile.m:15) 
1 UIKit        0x000000018a5fc2ac -[UIScrollView _willMoveToWindow:] + 172 
2 UIKit        0x000000018a5d5ca4 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 88 
3 UIKit        0x000000018a5d5b8c -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 460 
4 UIKit        0x000000018a5d5cc0 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 116 
5 UIKit        0x000000018a5d5b8c -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 460 
6 UIKit        0x000000018a5d5cc0 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 116 
7 UIKit        0x000000018a5d5b8c -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 460 
8 UIKit        0x000000018a8e85ac __UIViewWillBeRemovedFromSuperview + 460 
9 UIKit        0x000000018a5d4abc -[UIView(Hierarchy) removeFromSuperview] + 96 
10 UIKit        0x000000018a935b7c __71-[UIPresentationController _initViewHierarchyForPresentationSuperview:]_block_invoke596 + 344 
11 UIKit        0x000000018a9306f8 -[UIPresentationController transitionDidFinish:] + 124 
12 UIKit        0x000000018aa584d8 -[_UICurrentContextPresentationController transitionDidFinish:] + 44 
13 UIKit        0x000000018a933d9c __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2 + 188 
14 UIKit        0x000000018a70b668 -[_UIViewControllerTransitionContext completeTransition:] + 116 
15 UIKit        0x000000018a70b454 -[UITransitionView notifyDidCompleteTransition:] + 252 
16 UIKit        0x000000018a70af38 -[UITransitionView _didCompleteTransition:] + 1404 
17 UIKit        0x000000018a70a9a8 -[UITransitionView _transitionDidStop:finished:] + 124 
18 UIKit        0x000000018a616d3c -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 312 
19 UIKit        0x000000018a616bc4 -[UIViewAnimationState animationDidStop:finished:] + 108 
20 QuartzCore       0x0000000189dddc2c CA::Layer::run_animation_callbacks(void*) + 284 
21 libdispatch.dylib     0x000000019a3a96a8 _dispatch_client_callout + 16 
22 libdispatch.dylib     0x000000019a3aedb0 _dispatch_main_queue_callback_4CF + 1844 
23 CoreFoundation      0x00000001850001f8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 
24 CoreFoundation      0x0000000184ffe060 __CFRunLoopRun + 1628 
25 CoreFoundation      0x0000000184f2cca0 CFRunLoopRunSpecific + 384 
26 GraphicsServices     0x000000018ff94088 GSEventRunModal + 180 
27 UIKit        0x000000018a644ffc UIApplicationMain + 204 
28 MyApp        0x0000000100093918 main (main.m:16) 
29 libdyld.dylib      0x000000019a3da8b8 <redacted> + 4 


Binary Images: 
... 

Если я не найти более легкий подход , это будет способ пойти сейчас для меня. Может быть полезно создать скрипт, который вытаскивает стеки вызовов из файла журнала, удаляет ведущие пробелы и вставляет их в журнал сбоев.

+0

Это меня очень близко, но я никогда не получал символику для работы. Мое решение состояло в том, чтобы взять реальный журнал аварий и заменить содержимое одного потока моей ручной трассировкой стека. Запуск символа crash в этом файле – Miniroo

0

SYMBOLICATECRASH

компании Apple поставляется сценарий с XCode, что ускоряет процесс symbolication отчета аварии в полном объеме. Если у вас есть dSYM, бинарное приложение и отчет о сбоях, это, вероятно, самый простой способ обозначения. Вам не нужно беспокоиться ни о каком из адресов - этот скрипт будет анализировать весь файл дампа сбоя и использовать ATOS для разрешения всех адресов в символы для вас.

Найдите «symbolicatecrash» на вашей системе:

cd /Applications/Xcode.app 
find . -name symbolicatecrash 

Экспорт переменной среды DEVELOPER_DIR, если она не существует

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer" 

Скопируйте .app двоичный, отчет об аварии, и файл .dSYM во временную папку (например, ~/tmp). Запустите сценарий, как наш пример ниже:

/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash -v ApteligentExampleApp.crash ApteligentExampleApp.app.dSYM/ 

Если все пойдет хорошо, то сценарий должен symbolicate всему вашему врезаться файлу и выдавал результат в окно терминала.Этот скрипт не делает ничего, что вы не могли бы сделать вручную с помощью ATOS или другого инструмента, но он поможет вам быстрее.

Source