|
ВведениеCrashReporter Mac OS X является полезным средством для приобретения знаний о проблемах, которые Ваше приложение испытывает в поле. CrashReporter выполняет два полезных действия:
Рисунок 1: Первое диалоговое окно CrashReporter
Рисунок 2: Второе диалоговое окно CrashReporter
В этом technote я объясняю, как интерпретировать крешлоги, которые Вы получили из конечных пользователей. В первом разделе я объясняю каждую часть крешлога подробно. Следующий, который я показываю Вам, как можно получить полезную информацию от крешлога, даже если программа поставляет без отладочной информации. Тогда я объясняю, как использовать CrashReporterPrefs для настройки поведения CrashReporter. Наконец, я объясняю некоторые ограничения текущей реализации. IMPORTANT: Этот technote описывает CrashReporter, поскольку это реализовано в Mac OS X 10.5. CrashReporter развивался в течение долгого времени, и существуют многочисленные различия между текущей версией и более ранними. Я вызвал эти изменения, где они являются значительными. Примечание: CrashReporter ограничил поддержку некоторых осуждаемых технологий, прежде всего формат двухуровневого изображения PEF. Этот technote не описывает ту поддержку. Размещение крешлогаCrashReporter обычно помещает крешлог в корневой каталог пользователя, как объяснено выше. Однако при некоторых обстоятельствах это вставит крешлог
Каждый крешлог записан в отдельный файл. Имя файла имеет форму IMPORTANT: CrashReporter также создает другие файлы в каталоге CrashReporter. В частности это создает файлы формы Примечание: До Mac OS X 10.5 CrashReporter создали файлы формы Журналирование CrashReporterCrashReporter регистрирует через Системный Журнал Apple. Всем записям в журнале CrashReporter установили Средство для «Катастрофического отказа Генератора отчетов». Можно вывести на экран все такое сообщение с командой, показанной в Перечислении 1. Перечисление 1: Отображение всех записей в журнале CrashReporter $ syslog -k Facility eq "Crash Reporter" […] […] Formulating crash report for process TextEdit[9803] […] Saved crashreport to /Users/quinn/Library/Logs/CrashReporter/\ TextEdit_2008-01-29-204411_guy-smiley.crash using uid: 2000 gid: 2000, \ euid: 2000 egid: 2000 Можно вывести на экран недавние записи в журнале и ожидать больше для разоблачения (во многом как Перечисление 2: Ожидание новых записей в журнале CrashReporter $ syslog -w -k Facility eq "Crash Reporter" […] Можно сделать ту же вещь от Консольного приложения путем выбора New Log Database Query из меню File и затем конфигурирования запроса для поиска сообщений журнала, где Средство является «Генератором отчетов Катастрофического отказа». Примечание: До Mac OS X 10.5 CrashReporter зарегистрировали обоим системный журнал ( Версии крешлогаКрешлоги включают номер версии, который можно использовать для интерпретации информации, содержавшейся в журнале. Этот номер версии свободно связан с версией системы. Таблица 1 показывает то отношение. Таблица 1: версии крешлога
Анатомия крешлогаКрешлог имеет много различных частей; в следующих разделах я описываю каждую часть подробно. Информация о процессеПервая часть крешлога содержит информацию о процессе, отказавшем, как проиллюстрировано в Перечислении 3. Перечисление 3: информация о Процессе Process: TextEdit [8752] Path: /Applications/TextEdit.app/Contents/MacOS/TextEdit Identifier: com.apple.TextEdit Version: 1.5 (244) Build Info: TextEdit-2440000~2 Code Type: X86 (Native) Parent Process: launchd [241] Самой важной вещью отметить вот является имя отказавшего процесса. В некоторых случаях умерший фактический процесс не то, что Вы думаете. Например, если Ваше приложение использует инструмент помощника для выполнения некоторой работы, и тот инструмент помощника умирает, Вы хотите фокусироваться на коде инструмента помощника и не напрасно тратить время, отлаживая код приложения. Поле «Process» включает имя и PID (в квадратных скобках) разрушенного процесса. Поле «Path» является путем к исполнимой программе процесса. Поле «Identifier» содержит идентификатор пакета, если таковые имеются, разрушенного процесса. CrashReporter получает поле «Version» от исполнимой программы процесса. Если процесс является пакетным приложением, версия составлена из Поле «Build Info» показывает информацию, извлеченную из Поле «Code Type» показывает тип выполнявшегося кода. Если Ваша программа является универсальным двоичным файлом, необходимо проверить это поле для наблюдения, какая архитектура фактически выполнялась (например, пользователь, возможно, случайно выполнил программу с помощью Розетты). Поле «Parent Process» включает имя и PID (в квадратных скобках) родительского процесса. Стоит проверить, что это - то, чем Вы ожидали бы, что он будет. Примечание: В крешлогах до версии 6 поле «Process» было известно как поле «Command» и процесс, ID был включен в отдельное поле «PID». Примечание: Поля "Path" и "Version" были начаты с крешлогов версии 2. Примечание: Поле «Identifier» было начато с крешлогов версии 6. Примечание: В крешлогах до версии 6 информация в поле «Build Info» была разделена через три отдельных поля: «Версия сборки», «Название проекта» и «Исходная версия». Эти поля были начаты с крешлогов версии 3. Примечание: Поле «Code Type» было начато с крешлогов версии 6. Примечание: В крешлогах до версии 6 поле «Parent Process» назвали «Родителем». Это было сначала включено в крешлоги версии 3. Примечание: В крешлогах до версии 6 часть информации о процессе крешлога была помещена после части основной информации. Основная информацияСледующая часть крешлога содержит информацию о самом крешлоге. Вы видите пример в Перечислении 4. Перечисление 4: Основная информация Date/Time: 2008-01-29 12:32:46.239 +0000 OS Version: Mac OS X 10.5.1 (9B18) Report Version: 6 Самые важные данные здесь являются версией ОС. Необходимо обратить особое внимание на номер сборки; каждая видимая пользователем версия Mac OS X может иметь многократные варианты, которые отличают только их номера сборки (это обычно происходит для специфичных для аппаратных средств системных выпусков). Кроме того, удостоверьтесь, что посмотрели в это время и дата, чтобы видеть, существуют ли какие-либо подозрительные образцы: если Вы получаете много крешлогов, что все происходят в 12:00, вероятно, необходимо исследовать код обработки времени. Поле «Report Version» обсуждено в Версиях Крешлога. Примечание: Крешлоги версии 2 включали поле «Host Name» в этот раздел; это не присутствует в более поздних версиях. Информация об исключенииТретья часть крешлога показывает информацию об исключении процессора, которое было непосредственной причиной катастрофического отказа. Перечисление 5 показывает типичный пример. Перечисление 5: Информация об исключении Exception Type: EXC_BAD_ACCESS (SIGBUS) Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000000000000 Crashed Thread: 0 Поле «Crashed Thread» обозначает отказавший поток; это избыточно, потому что раздел следа выделяет отказывающий поток. Примечание: Поле «Crashed Thread» было представлено в крешлогах версии 2. До крешлогов версии 6 это вызвали «Потоком», и это появилось в разделе информации о процессе. Наиболее распространенные формы исключения:
Для исключений доступа к памяти ( Информация о следеЧетвертая часть крешлога, выводящего на экран след для всех потоков в разрушенном процессе, является обычно самой интересной. Перечисление 6 показывает пример. Перечисление 6: информация о Следе Thread 0 Crashed: 0 ??? 0000000000 0 + 0 1 com.apple.CoreFoundation 0x942cf0fe CFRunLoopRunSpecific + 18… 2 com.apple.CoreFoundation 0x942cfd38 CFRunLoopRunInMode + 88 3 com.apple.HIToolbox 0x919e58a4 RunCurrentEventLoopInMode… 4 com.apple.HIToolbox 0x919e56bd ReceiveNextEventCommon + … 5 com.apple.HIToolbox 0x919e5531 BlockUntilNextEventMatchi… 6 com.apple.AppKit 0x9390bd5b _DPSNextEvent + 657 7 com.apple.AppKit 0x9390b6a0 -[NSApplication nextEvent… 8 com.apple.AppKit 0x939046d1 -[NSApplication run] + 79… 9 com.apple.AppKit 0x938d19ba NSApplicationMain + 574 10 com.apple.TextEdit 0x00001df6 0x1000 + 3574 В этом примере существует только один поток, таким образом, существует только один след. В многопоточном процессе существует один след на поток. Таким образом критически важно, что Вы идентифицируете отказавший поток. CrashReporter делает это простым путем тегирования того следа с текстом «Поток Разрушенный <ThreadNumber>»:. Однако просто пропустить этот текст и ошибочно предположить, что Поток 0 является отказавшим тем. Примечание: Даже если Вы явно не создаете потоков, Ваш процесс может быть многопоточным. Различные платформы могут создать потоки от Вашего имени. Например, CFSocket создает поток для интеграции сокетов с runloop. Каждая строка следа описывает вызов вложенной функции (кадр) с последний раз выполняемой функцией наверху и наименее недавно выполненный в нижней части. Для каждого кадра столбцы в следе следующие.
Наконец, если Ваша программа многопоточна, можно часто идентифицировать, который поток который путем рассмотрения символьных имен глубоко в следе. Например, в Перечислении 6, структурируйте 9 списков Состояние потокаСледующая часть крешлога содержит дамп состояния процессора отказавшего потока. Перечисление 7 показывает пример этого для PowerPC. Перечисление 7: состояние потока PowerPC
Thread 0 crashed with PPC Thread State 64:
srr0: 0x0000000000000000 srr1: 0x000000004000d030 …
cr: 0x44022282 … lr: 0x000000009000a6bc…
r0: 0x00000000ffffffe1 r1: 0x00000000bfffeb10 r2: 0x00000000a…
r4: 0x0000000003000006 r5: 0x0000000000000000 r6: 0x000000000…
r8: 0x0000000000000000 r9: 0x0000000000000000 r10: 0x000000000…
r12: 0x000000009000a770 r13: 0x0000000000000000 r14: 0x000000000…
r16: 0x0000000000000000 r17: 0x0000000000000000 r18: 0x000000000…
r20: 0x00000000101a7026 r21: 0x00000000be5b19d8 r22: 0x000000000…
r24: 0x0000000000000450 r25: 0x0000000000001203 r26: 0x000000000…
r28: 0x0000000000000000 r29: 0x0000000003000006 r30: 0x000000000…
Чтобы получить все возможное от этой информации, Вам нужно хорошее понимание двоичного интерфейса приложений (ABI) Mac OS X для процессора. Для подробного описания посмотрите Mac OS X Руководство по Вызову функции ABI. Однако существуют некоторые простые пути, получают полезные результаты без полного понимания ABI. Архитектура PowerPCДля основанных на PowerPC компьютеров необходимо рассмотреть следующие моменты:
В примере в Перечислении 7 (который является состоянием потока для исключения доступа к памяти), Вы видите это Примечание: До версии 3 крешлоги только включают нижнюю часть 32 бита каждого регистра PowerPC. 32-разрядная архитектура IntelПеречисление 8 показывает состояние потока для основанного на Intel компьютера, выполняющего 32-разрядный код. Перечисление 8: 32-разрядное состояние потока Intel Thread 0 crashed with X86 Thread State (32-bit): eax: 0x00000000 ebx: 0x942cea07 ecx: 0xbfffed1c edx: 0x94b3a8e6 edi: 0x00000000 esi: 0x00000000 ebp: 0xbfffed58 esp: 0xbfffed1c ss: 0x0000001f efl: 0x00010206 eip: 0x00000000 cs: 0x00000017 ds: 0x0000001f es: 0x0000001f fs: 0x00000000 gs: 0x00000037 cr2: 0x00000000 Для основанных на Intel компьютеров, выполняющих 32-разрядный код, необходимо рассмотреть следующие моменты:
Примечание: Из-за пути работает архитектура Intel, более трудно получить полезные результаты состояния потока, чем это находится на PowerPC. Например, на архитектуре PowerPC обратный адрес сохранен в регистре ( Примечание: 32-разрядное состояние потока Intel в крешлогах до версии 6 не включало 64-разрядная архитектура IntelПеречисление 9 показывает состояние потока для основанного на Intel компьютера, выполняющего 64-разрядный код. Перечисление 9: 64-разрядное состояние потока Intel Thread 0 crashed with X86 Thread State (64-bit): rax: 0x0000000000000000 rbx: 0x0000000000000000 rcx: 0x00007fff5fbfec48… rdi: 0x00007fff5fbfed40 rsi: 0x0000000003000006 rbp: 0x00007fff5fbfeca0… r8: 0x0000000000001003 r9: 0x0000000000000000 r10: 0x0000000000000450… r12: 0x0000000000001003 r13: 0x0000000000000450 r14: 0x00007fff5fbfed40… rip: 0x0000000000000000 rfl: 0x0000000000010206 cr2: 0x0000000000000000 В целом необходимо интерпретировать это состояние потока почти таким же способом, поскольку Вы были бы 32-разрядное состояние потока Intel. Основные отличия:
Двухуровневые изображенияСледующая часть крешлога является описанием всех двухуровневых изображений, загруженных в процесс. Перечисление 10 является примером этого. Перечисление 10: двухуровневые изображения
Binary Images:
0x1000 - 0x18feb com.apple.TextEdit 1.5 (244) <e1480af78e2746195aa…
0xc648000 - 0xc72eff7 com.apple.RawCamera.bundle 2.0 (2.0) /System/Libr…
0x8fe00000 - 0x8fe2d883 dyld 95.3 (???) <81592e798780564b5d46b988f7ee1a6a…
0x90046000 - 0x9004efff com.apple.DiskArbitration 2.2 (2.2) <1551b2af557f…
0x9004f000 - 0x9004fff8 com.apple.ApplicationServices 34 (34) <8f910fa65f…
0x90056000 - 0x900affff libGLU.dylib ??? (???) /System/Library/Frameworks…
0x900b0000 - 0x900b0ffc com.apple.audio.units.AudioUnit 1.5 (1.5) /System…
0x900b1000 - 0x90163ffb libcrypto.0.9.7.dylib ??? (???) <330b0e48e67faffc…
[…]
Этот список особенно полезен, потому что можно использовать его для определения символьного следа в программе без символов. Может также быть полезно, если Ваша программа делает широкое применение плагинов, потому что это покажет Вам точно, какие плагины были загружены в Вашем процессе. Наконец, можно просмотреть этот список для библиотек, что Вы не ожидаете быть загруженными в Ваш процесс, такой как используемые исправлением распространенного приложения (или 'улучшение') технологии. Примечание: Этот раздел был начат с крешлогов версии 2. IMPORTANT: значение в угловых скобках является UUID изображения, если существующий. Изображение UUIDs важно при рассмотрении крешлогов без символов. Примечание: Двухуровневое изображение UUIDs было сначала включено в крешлоги версии 6. Розетта ЭкстрасЕсли разрушенный процесс был выполнен с помощью Розетты, дополнительная информация добавляется к крешлогу. Для запуска с поле «Code Type» в части информации о Процессе указывает, что использовалась Розетта; пример этого показан в Перечислении 11. Перечисление 11: информация о Процессе с Розеттой Process: TextEdit [9031] Path: /Applications/TextEdit.app/Contents/MacOS/TextEdit Identifier: com.apple.TextEdit Version: 1.5 (244) Code Type: PPC (Translated) Parent Process: launchd [241] Кроме того, «Переведенная часть» информации о Коде добавляется после раздела Binary Images. Этот раздел включает:
Перечисление 12 показывает пример этой информации. Перечисление 12: Переведенная информация о коде Translated Code Information: Rosetta Version: 20.44 Args: /Applications/TextEdit.app/Contents/MacOS/TextEdit -psn_0_2761378 Exception: EXC_BAD_ACCESS (0x0001) Thread 0: Crashed (0xb7fff9d0, 0xb80bc8c8) 0x40400000: No symbol 0x90a9b35c: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit… 0x90a9b290: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit… 0x90a9a7a8: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit… 0x90a9a0e0: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit… 0x90a99a1c: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit… 0x90a98458: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit… 0x90a6b8f4: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit… 0x909d8ed8: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit… 0x909a9930: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit… 0x00001e18: /Applications/TextEdit.app/Contents/MacOS/TextEdit : start + … 0x00000000: /Applications/TextEdit.app/Contents/MacOS/TextEdit : + 0 PPC Thread State srr0: 0x00000000 srr1: 0x00000000 vrsave: 0x00000000 cr: 0xXXXXXXXX xer: 0x00000000 lr: 0x90a9b35c ctr: 0x0000e814 r00: 0x90a9b35c r01: 0xbfffe5d0 r02: 0xa0bcf924 r03: 0x00234840 r04: 0x00020000 r05: 0x002adce0 r06: 0x002adce0 r07: 0x002adce0 r08: 0xa1b1c1d3 r09: 0x00000000 r10: 0x00000004 r11: 0x00000001 r12: 0x0000e814 r13: 0xa01da174 r14: 0xa01da174 r15: 0xa01da174 r16: 0xa01da174 r17: 0xa01da174 r18: 0x00000000 r19: 0x002c00b0 r20: 0xbfffe760 r21: 0xa01da174 r22: 0xa01da174 r23: 0xa01da174 r24: 0xa01ea174 r25: 0x002adce0 r26: 0x002475c0 r27: 0x00015dd4 r28: 0x00234840 r29: 0x00020000 r30: 0x00234840 r31: 0x90a9b2f0 Крешлоги без символовСимволы всегда представляли загадку для разработчиков:
Современные версии XCode упрощают иметь Ваш пирог и есть его к. Можно удалить все символы из программы прежде, чем поставить его в конечных пользователей, и все еще иметь легкий доступ к символьной информации об отладчике при интерпретации крешлогов. Этот раздел объясняет, как сделать это. Разделенные символыПри создании программы с XCode необходимо иметь дело с двумя совсем другими типами символов:
Мужественные символы подразделены на две группы:
XCode поддерживает две формы символов отладчика:
Примечание: Символы отладчика STABS фактически сохранены в Мужественной таблице символов. Это сделало процесс управляющих символов более запутывающим, потому что он соединял два совсем других понятия (т.е. Мужественные символы и символы отладчика). Разделение символов отладчикаРеализация DWARF XCode делает очень простым разделить символы отладчика из Вашей выпущенной программы. Все, что необходимо сделать, установлено «установка сборки» Формата Отладочной информации для сборки конечных версий к «DWARF с dSYM Файлом» (
Если, когда-либо в будущем, необходимо отладить выпущенную программу, можно просто поместить его и Разделение мужественных символовРазделение Мужественных символов является более сложной проблемой. Проблема состоит в том, что некоторые Мужественные символы интерпретируются во время выполнения динамическим компоновщиком, и необходимо гарантировать, что не разделяются те символы. Существует один общий подход, но Вы имеете, изменяют его в зависимости от типа программы, которую Вы создаете. Первый шаг должен включить «Развертывание, Постобрабатывающее» установку сборки (
Критически, значение по умолчанию для «установки сборки» Стиля Полосы зависит от Вашего целевого типа. Таблица 2 показывает это отношение. Таблица 2: стиль полосы По умолчанию целевым типом
IMPORTANT: Если Вы не установите «установку сборки» Стиля Полосы на уровне проекта, то XCode выведет на экран значение Всех Символов. Это вводит в заблуждение. Фактическое значение, которое Вы получаете, зависит от целевого типа, как показано выше. При открытии целевых настроек сборки Вы установите фактическое значение, которое будет использоваться. С другой стороны, при установке значения для «установки сборки» Стиля Полосы на уровне проекта это применится ко всем целям (если Вы не переопределите его в целевом слое). Если Ваш проект будет иметь многократные цели различных типов, то это вряд ли будет полезно. В этом случае Вы, вероятно, захотите установить «установку сборки» Стиля Полосы в целевом слое для всех целей. Для получения дополнительной информации о том, как настройки сборки XCode разделены на уровни, посмотрите раздел раздела Build Setting Evaluation Руководства пользователя XCode. Существует два общих подхода к разделению Мужественных символов:
Реализация типичного подхода тривиальна. Установите «установку сборки» Стиля Полосы в Отладочную информацию, и XCode оставит всю Вашу глобальную переменную и локальные Мужественные символы в программе. Этот подход работает на все целевые типы. Реализация ограниченного подхода немного более хитра. Необходимо сделать разные вещи в зависимости от целевого типа. Для приложения или инструмента командной строки, можно просто установить «установку сборки» Стиля Полосы во «Все Символы». Примечание: Это не удалит все символы из Вашей программы. Некоторые символы, как Для пакета, платформы или динамической библиотеки, необходимо разделить все локальные символы путем установки «установки сборки» Стиля Полосы в «Неглобальные Символы». Вы не можете, в целом, разделить глобальные символы, потому что на них можно сослаться динамично. IMPORTANT: возможно ограничить список глобальных символов путем передачи различных параметров полосе. Однако в большинстве случаев проще сделать это на этапе ссылки. Например, можно явно управлять списком экспортируемых символов путем установки «Экспортируемой установки сборки» Файла Символов ( Символы и CrashReporterКак только Вы установили свою систему сборки правильно, фактически довольно просто получить значимые результаты крешлога. Если Вы не разделите локальные Мужественные символы, то следы в Вашем крешлоге будут уже украшены корректными именами функций. Во многих случаях это - все, в чем Вы нуждаетесь. Однако существуют ситуации, где Вам нужно больше информации.
К счастью, это просто в использовании Ваш Позиционно-зависимый кодДля зависимого кода позиции (приложения и инструменты командной строки) процесс тривиален: поместите свою сборку конечных версий и Ваш Перечисление 13: Используя GDB для позиционно-зависимого кода $ # Get the numeric values from the backtrace... $ grep "Thread 0 Crashed:" -A 19 NoSymbolsTest_[…]_guy-smiley.crash Thread 0 Crashed: 0 ...le.dts.NoSymbolsTest.Bundle 0x107cbf99 0x107cb000 + 3993 1 ...le.dts.NoSymbolsTest.Bundle 0x107cbfcb 0x107cb000 + 4043 2 ...dts.NoSymbolsTest.Framework 0x10005f2e 0x10005000 + 3886 3 ...dts.NoSymbolsTest.Framework 0x10005f59 0x10005000 + 3929 4 com.apple.dts.NoSymbolsTest 0x10000edf 0x10000000 + 3807 5 com.apple.AppKit 0x939dcf94 -[NSApplication sendAction… 6 com.apple.AppKit 0x939dced4 -[NSControl sendAction:to:… 7 com.apple.AppKit 0x939dcd5a -[NSCell _sendActionFrom:]… 8 com.apple.AppKit 0x939dc3bb -[NSCell trackMouse:inRect… 9 com.apple.AppKit 0x939dbc12 -[NSButtonCell trackMouse:… 10 com.apple.AppKit 0x939db4cc -[NSControl mouseDown:] + … 11 com.apple.AppKit 0x939d9d9b -[NSWindow sendEvent:] + 5… 12 com.apple.AppKit 0x939a6a2c -[NSApplication sendEvent:… 13 com.apple.AppKit 0x93904705 -[NSApplication run] + 847… 14 com.apple.AppKit 0x938d19ba NSApplicationMain + 574 15 com.apple.dts.NoSymbolsTest 0x10000e36 0x10000000 + 3638 16 com.apple.dts.NoSymbolsTest 0x10000e02 0x10000000 + 3586 17 com.apple.dts.NoSymbolsTest 0x10000d29 0x10000000 + 3369 $ # Run GDB to get the symbolic information for the address in frame 4. $ gdb NoSymbolsTest.app GNU gdb 6.3.50-20050815 (Apple version gdb-768) […] (gdb) info line *0x10000edf Line 86 of "/Users/quinn/Crash Reporter/NoSymbolsTest/AppDelegate.m" \ starts at address 0x10000edf <-[AppDelegate testAction:]+104> and ends at \ 0x10000ee1 <-[AppDelegate testAction:]+106>. Существует много вещей рассмотреть при выполнении этого отображения.
Перечисление 14: Используя UUID, чтобы подтвердить, что Ваши символы соответствуют программу пользователя $ # Get the UUID from the binary images part of the crash log. $ # The UUID is displayed in angle brackets. $ grep "0x.*com.apple.dts.NoSymbolsTest .*<" NoSymbolsTest_[…]_guy-smiley.crash 0x10000000 - 0x10000ffe com.apple.dts.NoSymbolsTest ??? (1.0) \ <6264534bd26d5d39f7960cea770c4ea8> /Users/quinn/Crash Reporter/NoSymbolsTest/\ build/Release/NoSymbolsTest.app/Contents/MacOS/NoSymbolsTest $ # Get the UUID from the binary that we have. $ dwarfdump --uuid NoSymbolsTest.app/Contents/MacOS/NoSymbolsTest UUID: 6264534B-D26D-5D39-F796-0CEA770C4EA8 (i386) NoSymbolsTest.app[…] UUID: AA201B24-D09B-49E2-55E5-AB15AF63B12A (ppc) NoSymbolsTest.app[…] $ # Get the UUIDs from the .dSYM file. $ dwarfdump --uuid NoSymbolsTest.app.dSYM UUID: 6264534B-D26D-5D39-F796-0CEA770C4EA8 (i386) NoSymbolsTest.app.dSYM UUID: AA201B24-D09B-49E2-55E5-AB15AF63B12A (ppc) NoSymbolsTest.app.dSYM $ # Note that all three UUIDs match! Позиционно-независимый кодВещами является немного больше сложности для позиционно-независимого кода, как платформы, динамические библиотеки или пакеты. В этом случае необходимо разработать различие между тем, где код предназначался, чтобы быть загруженным и где был фактически загружен код. Это значение известно как понижение. Для нахождения адреса, что программа была фактически загружена посмотрите в части двухуровневых изображений крешлога. В примере в Перечислении 15 программа имеет три соответствующих двухуровневых изображения (основная программа, платформа и пакет) и, для каждого изображения, первый столбец вывода является адресом где Перечисление 15: Получение адреса действующей нагрузки $ # Determine the addresses that the programs were loaded. $ grep "0x.*com.apple.dts" NoSymbolsTest_[…]_guy-smiley.crash 0x10000000 - 0x10000ffe com.apple.dts.NoSymbolsTest ??? (1.0) […] 0x10005000 - 0x10005ffd com.apple.dts.NoSymbolsTest.Framework ??? (1.0) […] 0x107cb000 - 0x107cbffc com.apple.dts.NoSymbolsTest.Bundle ??? (1.0) […] Можно тогда использовать otool для получения намеченного адреса загрузки Перечисление 16: Получение намеченного адреса загрузки
$ otool -l NoSymbolsTest.app/Contents/MacOS/NoSymbolsTest \
| grep -B 3 -A 2 -m 1 "__TEXT"
Load command 1
cmd LC_SEGMENT
cmdsize 192
segname __TEXT
vmaddr 0x10000000
vmsize 0x00001000
$ otool -l NoSymbolsTest.app/Contents/Frameworks/Framework.framework/Framework \
| grep -B 3 -A 8 -m 1 "__TEXT"
Load command 0
cmd LC_SEGMENT
cmdsize 192
segname __TEXT
vmaddr 0x01000000
vmsize 0x00001000
$ otool -l NoSymbolsTest.app/Contents/Resources/Bundle.bundle/Contents/MacOS/Bundle \
| grep -B 3 -A 8 -m 1 "__TEXT"
Load command 0
cmd LC_SEGMENT
cmdsize 192
segname __TEXT
vmaddr 0x00000000
vmsize 0x00001000
Вычисление понижения является теперь вопросом основной арифметики. Таблица 3: вычисление понижения
IMPORTANT: основная исполнимая программа является почти всегда позиционно-зависимой, и таким образом ее понижение является нулем. Это - то, что делает метод описанным в Позиционно-зависимом Коде настолько более простой. Если Вы отображаете использование символов Перечисление 17: Используя GDB для позиционно-независимого кода $ # Get the addresses from the backtrace. $ grep "Thread 0 Crashed:" -A 5 NoSymbolsTest_2008-02-04-111412_guy-smiley.crash Thread 0 Crashed: 0 ...le.dts.NoSymbolsTest.Bundle 0x107cbf99 0x107cb000 + 3993 1 ...le.dts.NoSymbolsTest.Bundle 0x107cbfcb 0x107cb000 + 4043 2 ...dts.NoSymbolsTest.Framework 0x10005f2e 0x10005000 + 3886 3 ...dts.NoSymbolsTest.Framework 0x10005f59 0x10005000 + 3929 4 com.apple.dts.NoSymbolsTest 0x10000edf 0x10000000 + 3807 $ # Now map the addresses for the frames in the bundle (0 and 1). $ # Run GDB with no arguments. $ gdb GNU gdb 6.3.50-20050815 (Apple version gdb-768) […] (gdb) # Disable shared library preloading. See below for why. (gdb) set sharedlibrary preload-libraries off (gdb) # Target the bundle. (gdb) file Bundle.bundle/Contents/MacOS/Bundle Reading symbols from […] (gdb) # Subtract the bundle slide from the frame 0 address and then map it. (gdb) p/x 0x107cbf99-0x107cb000 $1 = 0xf99 (gdb) info line *$1 Line 28 of "/Users/quinn/Crash Reporter/NoSymbolsTest/Bundle.m" starts at address \ 0xf94 <-[Bundle testInner]+50> and ends at \ 0xfa5 <-[Bundle testInner]+67>. (gdb) # Subtract the bundle slide from the frame 1 address and then map it. (gdb) p/x 0x107cbfcb-0x107cb000 $2 = 0xfcb (gdb) info line *$2 Line 34 of "/Users/quinn/Crash Reporter/NoSymbolsTest/Bundle.m" starts at address \ 0xfcb <-[Bundle testOuter]+36> and ends at \ 0xfd1 <-[Bundle testOuter]+42>. (gdb) quit $ # Now do the same for the framework. $ gdb GNU gdb 6.3.50-20050815 (Apple version gdb-768) […] (gdb) # Disable shared library preloading. (gdb) set sharedlibrary preload-libraries off (gdb) # Target the framework. (gdb) file Framework.framework/Framework Reading symbols from […] (gdb) # Subtract the framework slide from the frame 2 address and then map it. (gdb) p/x 0x10005f2e-0x0F005000 $1 = 0x1000f2e (gdb) info line *$1 Line 39 of "/Users/quinn/Crash Reporter/NoSymbolsTest/Framework.m" starts at address \ 0x1000f2e <-[Framework testInner]+308> and ends at 0x1000f35 <-[Framework testOuter]>. (gdb) # Subtract the framework slide from the frame 3 address and then map it. (gdb) p/x 0x10005f59-0x0F005000 $2 = 0x1000f59 (gdb) info line *$2 Line 44 of "/Users/Crash Reporter/NoSymbolsTest/Framework.m" starts at address \ 0x1000f59 <-[Framework testOuter]+36> and ends at \ 0x1000f5f <-[Framework testOuter]+42>. IMPORTANT: По умолчанию, когда Вы предназначаетесь для файла в GDB (использующий Примечание: Программа, используемая в примерах в этом разделе, была тщательно создана для осуществления некоторых интересных граничных случаев. Однако это производит некоторые эффекты, которые довольно нетипичны. Прежде всего при создании платформы Вы обычно обнуляете ее намеченный адрес загрузки или значение, не перекрывающее Вашу основную исполнимую программу. Таким образом платформа обычно имеет или нуль предназначенный адрес загрузки или нулевое понижение. Примечание: Этот раздел фокусируется на Дурные вести - то, что крешлог не содержит базовый адрес
CrashReporterPrefsПриложение CrashReporterPrefs (установленный как часть инструментов разработчика XCode) позволяет Вам управлять, как работает CrashReporter. Рисунок 3 показывает свой основной пользовательский интерфейс. Рисунок 3: пользовательский интерфейс CrashReporterPrefs
Существует три режима:
Рисунок 4: CrashReporter в режиме Developer
Примечание: CrashReporterPrefs был начат с Mac OS X 10.4 (Xcode 2.0). До Mac OS X 10.4, не было никакого эквивалента режиму Developer. Вы могли, однако, изменить некоторое поведение CrashReporter с помощью скрытых предпочтений, как описано в Технических Вопросах и ответах QA1288, 'Подавив «неожиданно выход» предупреждение'. В Mac OS X 10.4.x Developer режим предложил бы Вам опцию присоединения к разрушенному процессу с помощью GDB. Эта функция была удалена, потому что изменения в архитектуре в системе, разработанной для создания катастрофического отказа, сообщающего более надежном в целом, сделали ее очень трудно для реализации. Ограничения CrashReporterCrashReporter в настоящее время имеет много ограничений.
Много проблем, влиявших на предыдущие версии CrashReporter, были, адресовались в Mac OS X 10.5.
Дополнительные материалы для чтенияDownloadables
История версии документа
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||



