Spec-Zone .ru
спецификации, руководства, описания, API
Библиотека разработчика Mac Разработчик
Поиск

CrashReporter

CrashReporter является средством отладки в Mac OS X, регистрирующем информацию обо всех программах тот катастрофический отказ. Этот technote описывает CrashReporter подробно. Это включает описание крешлогов, сгенерированных CrashReporter, и как можно использовать эти журналы для отладки программы.

Этот technote полезен для любого, кто разрабатывает программное обеспечение пространства пользователя Mac OS X.

Введение

CrashReporter Mac OS X является полезным средством для приобретения знаний о проблемах, которые Ваше приложение испытывает в поле. CrashReporter выполняет два полезных действия:

  • Когда программа откажет, CrashReporter запишет крешлог (обычно в ~/Library/Logs/CrashReporter/), и сообщите пользователю путем журналирования сообщения к системному средству журналирования.

  • Кроме того, если отказавшая программа будет работать как зарегистрированный пользователь GUI, то CrashReporter подарит пользователю диалоговое окно, спрашивая их, хотят ли они представить отчет об ошибках Apple (см. рисунок 1). Если пользователь нажимает кнопку Report, CrashReporter выводит на экран другое диалоговое окно, показывающее подробные данные отчета (см. рисунок 2), и позволяет им комментировать его перед представлением.

Рисунок 1: Первое диалоговое окно CrashReporter

Figure 1, First CrashReporter dialog

Рисунок 2: Второе диалоговое окно CrashReporter

Figure 2, Second CrashReporter dialog

В этом technote я объясняю, как интерпретировать крешлоги, которые Вы получили из конечных пользователей. В первом разделе я объясняю каждую часть крешлога подробно. Следующий, который я показываю Вам, как можно получить полезную информацию от крешлога, даже если программа поставляет без отладочной информации. Тогда я объясняю, как использовать CrashReporterPrefs для настройки поведения CrashReporter. Наконец, я объясняю некоторые ограничения текущей реализации.

IMPORTANT: Этот technote описывает CrashReporter, поскольку это реализовано в Mac OS X 10.5. CrashReporter развивался в течение долгого времени, и существуют многочисленные различия между текущей версией и более ранними. Я вызвал эти изменения, где они являются значительными.

Примечание: CrashReporter ограничил поддержку некоторых осуждаемых технологий, прежде всего формат двухуровневого изображения PEF. Этот technote не описывает ту поддержку.

Размещение крешлога

CrashReporter обычно помещает крешлог в корневой каталог пользователя, как объяснено выше. Однако при некоторых обстоятельствах это вставит крешлог /Library/Logs/CrashReporter/. Они включают:

  • если это не может определить владение разрушенного процесса

  • если разрушенный процесс принадлежал корню

  • если корневой каталог пользователя не доступен или не перезаписываем

Каждый крешлог записан в отдельный файл. Имя файла имеет форму PPP_YYYY-MM-DD-HHMMSS_NNN.crash, где PPP является именем процесса; YYYY, MM, DD, HH, MM и SS являются датой и временем катастрофического отказа; и NNN является именем хоста. Например, TextEdit_2008-01-29-143702_guy-smiley.crash катастрофический отказ TextEdit от 29 Янов 2008 в 14:37:02 на машине «смайлик парня». Для предотвращения неограниченного дискового использования CrashReporter ограничивает число файлов крешлога для любой данной комбинации пользователя, имени процесса и имени хоста. Ограничение по току равняется 20.

IMPORTANT: CrashReporter также создает другие файлы в каталоге CrashReporter. В частности это создает файлы формы .PPP_NNN_CrashHistory.plist (например, .TextEdit_guy-smiley_CrashHistory.plist). Эти файлы невидимы в Средстве поиска. Вы не должны полагаться на присутствие или формат этих файлов.

Примечание: До Mac OS X 10.5 CrashReporter создали файлы формы PPP.crash.log, где PPP является именем процесса. Все крешлоги для данного имени процесса были добавлены к тому файлу. Например, все катастрофические отказы TextEdit были зарегистрированы TextEdit.crash.log. Не было ничего, чтобы препятствовать тому, чтобы эти файлы росли без связанного.

Назад к началу. 

Журналирование CrashReporter

CrashReporter регистрирует через Системный Журнал 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

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

Перечисление 2: Ожидание новых записей в журнале CrashReporter

$ syslog -w -k Facility eq "Crash Reporter"
[…]

Можно сделать ту же вещь от Консольного приложения путем выбора New Log Database Query из меню File и затем конфигурирования запроса для поиска сообщений журнала, где Средство является «Генератором отчетов Катастрофического отказа».

Примечание: До Mac OS X 10.5 CrashReporter зарегистрировали обоим системный журнал (/var/log/system.log) и его собственный определенный файл журнала (/var/log/crashreporter.log).

Назад к началу. 

Версии крешлога

Крешлоги включают номер версии, который можно использовать для интерпретации информации, содержавшейся в журнале. Этот номер версии свободно связан с версией системы. Таблица 1 показывает то отношение.

Таблица 1: версии крешлога

Версия крешлогаВерсии Mac OS X
1до 10.3.2
210.3.2 до 10.3.9
310.4.x на PowerPC
410.4.x на Intel
5ни один
610.5 и позже

Назад к началу. 

Анатомия крешлога

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

Информация о процессе

Первая часть крешлога содержит информацию о процессе, отказавшем, как проиллюстрировано в Перечислении 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» от исполнимой программы процесса. Если процесс является пакетным приложением, версия составлена из CFBundleShortVersionString и CFBundleVersion свойства от Info.plist файл. Если процесс является единственным приложением файла, версия получена из 'vers' Ресурс ID=1.

Поле «Build Info» показывает информацию, извлеченную из version.plist файл в пакете приложения, если таковые имеются. Этот файл, и следовательно это поле, обычно только присутствуют для приложений Apple.

Поле «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 это вызвали «Потоком», и это появилось в разделе информации о процессе.

Наиболее распространенные формы исключения:

  • EXC_BAD_ACCESS/KERN_INVALID_ADDRESS — Это вызывается потоком, получающим доступ к неотображенной памяти. Это может быть инициировано или доступом к данным или вызовом команды; раздел Thread State описывает, как сказать различие.

  • EXC_BAD_ACCESS/KERN_PROTECTION_FAILURE — Это вызывается потоком, пытающимся записать в постоянную память. Это всегда вызывается доступом к данным.

  • EXC_BAD_INSTRUCTION — Это вызывается потоком, выполняющим запрещенную команду.

  • EXC_ARITHMETIC/EXC_I386_DIV — Это вызывается потоком, делающим целочисленное деление нулем на основанном на Intel компьютере.

Для исключений доступа к памяти (EXC_BAD_ACCESS) часть исключения крешлога содержит адрес, инициировавший исключение (адрес исключения). В Перечислении 5, что адрес является 0x0000000000000000.

Назад к началу. 

Информация о следе

Четвертая часть крешлога, выводящего на экран след для всех потоков в разрушенном процессе, является обычно самой интересной. Перечисление 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.

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

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

  • Второй столбец является именем двухуровневого изображения, содержащего код, выполняющийся в этом кадре; это получено перекрестными ссылками адрес счетчика команд (от следующего столбца) со списком загруженных двухуровневых изображений.

  • Третий столбец является адресом счетчика команд в кадре. Для кадра 0 это обычно - адрес инструкции, вызвавшей исключение. Для более высоких кадров это - обратный адрес для того кадра. Т.е. для кадра N это указывает на следующую инструкцию, которая выполнится когда функция, на которую ссылается кадр N - 1 возврат.

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

Наконец, если Ваша программа многопоточна, можно часто идентифицировать, который поток который путем рассмотрения символьных имен глубоко в следе. Например, в Перечислении 6, структурируйте 9 списков NSApplicationMain как его символический адрес, указывая, что этот поток является основным потоком. Напротив, самый глубокий кадр для pthread всегда является подпрограммой _pthread_start.

Назад к началу. 

Состояние потока

Следующая часть крешлога содержит дамп состояния процессора отказавшего потока. Перечисление 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 компьютеров необходимо рассмотреть следующие моменты:

  • Внимание на три значения: srr0, lr, и адрес исключения (описал ранее).

  • srr0 счетчик команд в то время, когда произошло исключение. Т.е. это - адрес инструкции, вызвавшей исключение. Для большинства исключений недоступа к памяти (например, EXC_BAD_INSTRUCTION вызванный путем выполнения запрещенной команды), это - значение ключа. Для исключений доступа к памяти это - только часть уравнения.

  • lr обычно используется для содержания обратного адреса вызова функции.

  • Для исключений доступа к памяти:

    • Если srr0 равно адресу исключения, исключение было вызвано выбирающими инструкциями. Обычно это означает, что Вы вызвали поддельный указатель функции (или, эквивалентно, вызвали метод на поддельном объекте). В этом случае обратный адрес обычно находится в lr, который говорит Вам адрес кода который названный поддельным указателем функции.

    • Кроме того, если srr0 равно lr который равен адресу исключения, Ваша программа разрушила возврат из функции. Это обычно означает повреждение штабеля (обратный адрес обычно сохраняется на штабеле во время выполнения функции), и затем умер, возвратившись к поддельному адресу.

    • Если srr0 не равно адресу исключения, исключение было вызвано инструкцией доступа к памяти (с точки зрения C, это означает разыменование недопустимого указателя).

  • Вызов функции ABI для кода PowerPC регистрируется базируемый; таким образом, если Вы отказываете рано в выполнении функции, можно быть в состоянии видеть ее параметры в регистрах. Посмотрите Mac OS X Руководство по Вызову функции ABI для подробных данных.

  • Наконец, может быть полезно просмотреть другие регистры для контрольных знаков. Например, если регистр содержит символы ASCII, значение которых только появляются в одном месте в Вашей программе, это - подсказка относительно того, что код недавно выполнил. Также, если регистр содержит известное ошибочное значение (например, dskFulErr, что означает «диск полная ошибка» в Файловом менеджере Core Services, значение которого-34, или 0xffffffde в шестнадцатеричном числе), который мог бы быть подсказкой относительно того, почему Ваша программа перестала работать.

В примере в Перечислении 7 (который является состоянием потока для исключения доступа к памяти), Вы видите это srr0 0x00000000, который равен адресу исключения (см. Информацию об исключении), но не равно lr. Таким образом программа отказала путем вызова a NULL указатель функции и адрес вызывающей стороны находятся в lr.

Примечание: До версии 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-разрядный код, необходимо рассмотреть следующие моменты:

  • Внимание на два значения: eip и адрес исключения (описал ранее).

  • eip счетчик команд в то время, когда произошло исключение. Т.е. это - адрес инструкции, вызвавшей исключение. Для большинства исключений недоступа к памяти (например, EXC_ARITHMETIC/EXC_I386_DIV вызванный целочисленным делением на нуль), это - значение ключа.

  • Для исключений доступа к памяти:

    • Если eip равно адресу исключения, исключение было вызвано выбирающими инструкциями. Обычно это означает:

      • Вы вызвали поддельный указатель функции (или, эквивалентно, вызвали метод на поддельном объекте),

      • Вы возвратились к плохому адресу, который, в свою очередь, средние значения, что Вы повредили штабель

    • Если eip не равно адресу исключения, исключение было вызвано инструкцией доступа к памяти (с точки зрения C, это означает разыменование недопустимого указателя).

  • Наконец, как с PowerPC, может быть полезно просмотреть другие регистры для контрольных знаков.

Примечание: Из-за пути работает архитектура Intel, более трудно получить полезные результаты состояния потока, чем это находится на PowerPC. Например, на архитектуре PowerPC обратный адрес сохранен в регистре (lr), в то время как на Intel это сохранено на штабеле.

Примечание: 32-разрядное состояние потока Intel в крешлогах до версии 6 не включало cr2 регистр.

Назад к началу. 

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. Основные отличия:

  • Адрес PC находится в rip, нет eip.

  • Как с PowerPC, вызов функции ABI для 64-разрядного кода Intel регистрируется базируемый; таким образом, если Вы отказываете рано в выполнении функции, можно быть в состоянии видеть ее параметры в регистрах. Посмотрите Mac OS X Руководство по Вызову функции ABI для подробных данных.

Назад к началу. 

Двухуровневые изображения

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

  • Мужественные Символы — Эти символы могут быть интерпретированы компоновщиком (или статичный, ld, или динамичные, dyld).

  • Символы отладчика — Эти символы интерпретируются отладчиком.

Мужественные символы подразделены на две группы:

  • локальные символы — Эти символы проигнорированы компоновщиком и исключительно присутствуют в пользу инструментов как CrashReporter. Когда Вы объявляете функцию как static в C это зарегистрировано как локальный символ.

  • глобальные символы — Эти символы интерпретируются и статическим и динамическим компоновщиком. Когда Вы объявляете функцию как extern в C это зарегистрировано как глобальный символ.

XCode поддерживает две формы символов отладчика:

  • DWARF — Это - современный формат символов отладчика, поддерживаемый Xcode 2.3 и позже. Символы DWARF имеют многочисленные преимущества, не наименьшее количество являющееся хорошей интеграцией с CrashReporter, как описано ниже.

  • STABS — Этот более старый формат символов отладчика теперь осуждается.

Примечание: Символы отладчика STABS фактически сохранены в Мужественной таблице символов. Это сделало процесс управляющих символов более запутывающим, потому что он соединял два совсем других понятия (т.е. Мужественные символы и символы отладчика).

Назад к началу. 

Разделение символов отладчика

Реализация DWARF XCode делает очень простым разделить символы отладчика из Вашей выпущенной программы. Все, что необходимо сделать, установлено «установка сборки» Формата Отладочной информации для сборки конечных версий к «DWARF с dSYM Файлом» (DEBUG_INFORMATION_FORMAT = dwarf-with-dsym). При создании программы, XCode извлечет всю отладочную информацию и поместит ее в a .dSYM документ, который это помещает прямо рядом с Вашей программой в папке сборки. Вы можете тогда:

  • пакет Ваша программа и поставка это Вашим пользователям

  • заархивируйте .dSYM файл

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

Назад к началу. 

Разделение мужественных символов

Разделение Мужественных символов является более сложной проблемой. Проблема состоит в том, что некоторые Мужественные символы интерпретируются во время выполнения динамическим компоновщиком, и необходимо гарантировать, что не разделяются те символы. Существует один общий подход, но Вы имеете, изменяют его в зависимости от типа программы, которую Вы создаете.

Первый шаг должен включить «Развертывание, Постобрабатывающее» установку сборки (DEPLOYMENT_POSTPROCESSING = YES) для Вашей сборки конечных версий. Это заставит XCode автоматически удалять некоторые символы из Вашей программы. Точное поведение зависит от «установки сборки» Стиля Полосы. У Вас есть три выбора для этой установки:

  • Все символы (STRIP_STYLE = all) — XCode разделит все символы, в частности не отмеченные как необходимый во время выполнения. Это эквивалентно рабочему инструменту полосы с флагами «-u» и «-r».

  • Неглобальные символы (STRIP_STYLE = non-global) — XCode разделит все локальные символы. Это эквивалентно рабочему инструменту полосы с флагами «-x».

  • Отладочная информация (STRIP_STYLE = debugging) — XCode не разделит символов! Фактически, это выполняет инструмент полосы с флагом «-S», заставляющим его удалять все символы отладчика. Это релевантно при использовании символов отладчика STABS. Однако, если Вы будете разумны и будете использовать DWARF, то Ваши символы отладчика не будут затронуты этим; strip удалит некоторую информацию из Вашей программы (особенно карта отладки, используемая dsymutil), но это не будет влиять .dSYM файл, который уже создал XCode.

Критически, значение по умолчанию для «установки сборки» Стиля Полосы зависит от Вашего целевого типа. Таблица 2 показывает это отношение.

Таблица 2: стиль полосы По умолчанию целевым типом

Тип TargetМужественный типСтиль полосы по умолчанию
Приложение, инструмент командной строкиMH_EXECUTEВсе символы
ПакетMH_BUNDLEНеглобальные символы
Платформа, динамическая библиотекаMH_DYLIBОтладочная информация
Статическая библиотекаMH_OBJECTОтладочная информация

IMPORTANT: Если Вы не установите «установку сборки» Стиля Полосы на уровне проекта, то XCode выведет на экран значение Всех Символов. Это вводит в заблуждение. Фактическое значение, которое Вы получаете, зависит от целевого типа, как показано выше. При открытии целевых настроек сборки Вы установите фактическое значение, которое будет использоваться.

С другой стороны, при установке значения для «установки сборки» Стиля Полосы на уровне проекта это применится ко всем целям (если Вы не переопределите его в целевом слое). Если Ваш проект будет иметь многократные цели различных типов, то это вряд ли будет полезно. В этом случае Вы, вероятно, захотите установить «установку сборки» Стиля Полосы в целевом слое для всех целей.

Для получения дополнительной информации о том, как настройки сборки XCode разделены на уровни, посмотрите раздел раздела Build Setting Evaluation Руководства пользователя XCode.

Существует два общих подхода к разделению Мужественных символов:

  • типичный — В большинстве случаев разумно оставить все Мужественные глобальные и локальные символы в Вашей программе выпуска. Они не чрезмерно увеличивают размер программы слишком много, и их присутствие может быть полезным. Например:

    • Ваши журналы CrashReporter будут включать основные символы в след

    • можно установить точки зонда DTrace на этих символах

  • ограниченный — В некоторых случаях необходимо удалить все несущественные символы из программы. Например:

    • когда Вы хотите сократить размер программы как можно больше

    • когда Вы не хотите пользователей, видящих Ваши имена символа

Реализация типичного подхода тривиальна. Установите «установку сборки» Стиля Полосы в Отладочную информацию, и XCode оставит всю Вашу глобальную переменную и локальные Мужественные символы в программе. Этот подход работает на все целевые типы.

Реализация ограниченного подхода немного более хитра. Необходимо сделать разные вещи в зависимости от целевого типа. Для приложения или инструмента командной строки, можно просто установить «установку сборки» Стиля Полосы во «Все Символы».

Примечание: Это не удалит все символы из Вашей программы. Некоторые символы, как _NXArgc, экспортируются как часть системы во время выполнения C, и Ваша программа не будет работать правильно при разделении их.

Для пакета, платформы или динамической библиотеки, необходимо разделить все локальные символы путем установки «установки сборки» Стиля Полосы в «Неглобальные Символы». Вы не можете, в целом, разделить глобальные символы, потому что на них можно сослаться динамично.

IMPORTANT: возможно ограничить список глобальных символов путем передачи различных параметров полосе. Однако в большинстве случаев проще сделать это на этапе ссылки. Например, можно явно управлять списком экспортируемых символов путем установки «Экспортируемой установки сборки» Файла Символов (EXPORTED_SYMBOLS_FILE). Также можно использовать атрибут видимости для явного объявления видимости символов в исходном коде.

Назад к началу. 

Символы и CrashReporter

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

Однако существуют ситуации, где Вам нужно больше информации.

  • При устранении всех несущественных Мужественных символов из программы (ограниченный подход, описанный в предыдущем разделе), след не будет украшен вообще.

  • Поскольку CrashReporter не имеет доступа к Вашим символам отладчика, это ничего не знает о Вашем исходном коде. Таким образом, когда это украшает след, это может только включать смещение, в байтах, с начала функции. Во многих случаях может быть трудно отобразить то байтовое смещение на Ваш строка в Вашем исходном коде.

К счастью, это просто в использовании Ваш .dSYM файл для получения информации исходного уровня от следа крешлога. Процесс немного отличается для позиционно-зависимого и позиционно-независимого кода.

Позиционно-зависимый код

Для зависимого кода позиции (приложения и инструменты командной строки) процесс тривиален: поместите свою сборку конечных версий и Ваш .dSYM файл в том же каталоге и использовании GDB для получения символьной информации для числовых адресов. Перечисление 13 показывает пример этого.

Перечисление 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>.

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

  • В Перечислении 13 я использовал GDB для отображения от адреса до символа. Другая опция состоит в том, чтобы использовать atos. Однако atos не будет работать правильно, если Вы разделили все несущественные Мужественные символы из программы (r. 4851020).

  • Для метода в Перечислении 13 для работы правильно у Вас должен быть доступ к программе, которую пользователь выполняет, и к соответствию .dSYM файл. Все три должны соответствовать точно. Можно подтвердить это соответствие с помощью UUID программы. Перечисление 14 показывает, как получить UUID от части двухуровневых изображений крешлога из самой программы (использующий dwarfdump), и от .dSYM файл (также использование dwarfdump).

  • Примеры в этом тексте предполагают, что Вы используете ту же архитектуру среды выполнения в качестве пользователя Вашей программы. Если это не так можно использовать параметр командной строки, чтобы вынудить инструменты использовать надлежащую архитектуру. Опция обычно -arch xxx, где xxx желаемая архитектура (например, i386 или ppc), несмотря на то, что для dwarfdump это --arch xxx.

Перечисление 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 программа имеет три соответствующих двухуровневых изображения (основная программа, платформа и пакет) и, для каждого изображения, первый столбец вывода является адресом где __TEXT сегмент был загружен.

Перечисление 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 для получения намеченного адреса загрузки __TEXT сегмент. Перечисление 16 показывает пример этого.

Перечисление 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: вычисление понижения

ПрограммаАдрес действующей нагрузки (A)Намеченный адрес загрузки (I)Понижение (-I)
основная исполнимая программа0x100000000x100000000
платформа0x100050000x010000000x0F005000
пакет0x107cb0000x000000000x107cb000

IMPORTANT: основная исполнимая программа является почти всегда позиционно-зависимой, и таким образом ее понижение является нулем. Это - то, что делает метод описанным в Позиционно-зависимом Коде настолько более простой.

Если Вы отображаете использование символов atos, можно подать это понижение в программу с помощью -s опция. При использовании GDB ситуация более сложна. Перечисление 17 показывает один метод для того, чтобы сделать это.

Перечисление 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 (использующий file команда), GDB загрузит символы для того файла и для всех совместно используемых библиотек, на которые это ссылается. Это может вызвать проблемы в ситуациях как это, где совместно используемые библиотеки могли бы перекрыть программу, о символах которой Вы заботитесь. set sharedlibrary preload-libraries off команда препятствует тому, чтобы GDB загрузил символы из совместно используемых библиотек. Это обладает дополнительным преимуществом того, чтобы заставлять вещи пойти быстрее.

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

Примечание: Этот раздел фокусируется на __TEXT сегмент, потому что символы в следе обычно прибывают из того сегмента. Для большинства Мужественных изображений __TEXT и __DATA сегменты скользят вместе; как только Вы разрабатываете понижение для __TEXT сегмент, можно применить то же понижение для отображения символов в __DATA сегмент. Однако в Mac OS X 10.5 и позже для этих сегментов возможно скользить независимо. Это обычно только происходит для обычно используемых системных платформ.

Дурные вести - то, что крешлог не содержит базовый адрес __DATA сегмент, таким образом, невозможно вычислить понижение данных изображения просто от крешлога (r. 5734989). Хорошие новости - то, что это редко необходимо потому что:

  • эта проблема только влияет на платформы, помещающиеся в совместно использованную область dyld (т.е. обычно используемые системные платформы)

  • редко для адресов сегмента данных появиться в следе

  • если они делают, и адрес находится в системной платформе, CrashReporter уже отобразит адрес на символ

Назад к началу. 

CrashReporterPrefs

Приложение CrashReporterPrefs (установленный как часть инструментов разработчика XCode) позволяет Вам управлять, как работает CrashReporter. Рисунок 3 показывает свой основной пользовательский интерфейс.

Рисунок 3: пользовательский интерфейс CrashReporterPrefs

Figure 3, CrashReporterPrefs user interface

Существует три режима:

  • Основной — Это - режим по умолчанию, описанный ранее.

  • Разработчик — Этот режим разработан для разработчиков программного обеспечения. В этом режиме CrashReporter выведет на экран более подробный катастрофический отказ, сообщает диалоговое окно в большем количестве случаев. Рисунок 4 показывает пример первого диалогового окна CrashReporter при выполнении в режиме Developer.

  • Сервер — Этот режим разработан для необслуживаемых серверов. Пользовательский интерфейс CrashReporter никогда не показывается, несмотря на то, что крешлоги все еще записаны в диск.

Рисунок 4: CrashReporter в режиме Developer

Figure 4, CrashReporter in Developer mode

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

Назад к началу. 

Ограничения CrashReporter

CrashReporter в настоящее время имеет много ограничений.

  • В настоящее время нет никакого способа для сторонних разработчиков получить доступ к отчетам, представленным через CrashReporter. Apple знает, что существует высокий спрос на такое средство (r. 3356232). Фактически, различные сторонние разработчики реализовали свои собственные механизмы создания отчетов катастрофического отказа: они колеблются от простого (имейте приложение, смотрят на его собственный файл крешлога во время запуска; если это изменилось, предложение утверждать, что это разработчику) к чрезмерному комплексу (полностью повторно реализуют CrashReporter).

  • Добавление некоторых данных стека к крешлогу сделало бы его более полезным при отладке определенных типов катастрофических отказов (r. 3310695).

Много проблем, влиявших на предыдущие версии CrashReporter, были, адресовались в Mac OS X 10.5.

  • Если Ваша программа завершилась из-за, до Mac OS X 10.5, CrashReporter не генерировал крешлог abort системный вызов (r. 3291139).

  • До Mac OS X 10.5, если Вы записали программу, которые вызывают исключение, но обработали то исключение через сигнальный обработчик, CrashReporter ошибочно генерирует крешлог для Вашей программы (r. 2941263).

Назад к началу. 

Дополнительные материалы для чтения

Назад к началу. 

Downloadables

Назад к началу. 

История версии документа

ДатаПримечания
01.04.2008Исправленный долгосрочный ввод с опечатками srr0 регистрируют имя.
27.02.2008Обновленный для Mac OS X 10.5, включая описание крешлогов версии 6 и полную перезапись раздела «Crash Logs Without Symbols» для учета DWARF.
28.02.2006Обновленный для Mac OS X 10.4.4 и на PowerPC - и на основанных на Intel компьютерах. Включенный описание крешлогов версии 3 и версии 4 и CrashReporterPrefs.
09.09.2004Описывает CrashReporter и как отладить с крешлогами.