dtraceотладка iOS приложений с помощью dtrace
В двух словах
• вызовы функций
• скрипты
• OS X / iOS Simulator
История
• truss (Unix)
• strace (Linux)
• dtrace (Sun OS, OS X)
Скрипт
<probe description> [/predicate/] { <actions> }
Скрипт
syscall::read:entry /execname == “bash”/ { printf(“bash with pid %d called write\n”,pid); }
Точка трассировки
Дополнительное условие
Действия
Скрипт
CPU ID FUNCTION:NAME 0 155 read:entry bash with pid 2958 called write 0 155 read:entry bash with pid 444 called write 1 155 read:entry bash with pid 448 called write 1 155 read:entry bash with pid 448 called write
Точки трассировки
provider:module:function:name
syscall, pid, objc read, write, +alloc
libc++.1.dylib, mach_kernel имя зонда (probe)
Точки трассировки
syscall::read:entryвход в функцию read для
всех процессов
Точки трассировки
syscall::read:returnвыход из read для всех
процессов
Точки трассировки
pid1234::read:выход и выход из read для
процесса с pid: 1234
Точки трассировки
objc123:NSString:-*:entryвход во все методы
NSString для процесса 123
Точки трассировки
syscall::read:entry, syscall::write:entry
Можно указывать несколько через запятую
Точки трассировки
BEGIN END
Специальные точки
Скрипт
syscall::read:entry /execname == “bash”/ { printf(“bash with pid %d called write\n”,pid); }
Дополнительное условие
Предикат
/expression/
Предикат
execname, pid, tid
Предикат
arg0..argX args[0]..args[X]
Предикат
перменные скрипта
Скрипт
syscall::read:entry /execname == “bash”/ { printf(“bash with pid %d called write\n”,pid); }
Действия
Скрипт
• Переменные
• Вызов функций
• Нет циклов и ветвлений
trace
syscall::read:entry{trace(execname)} !CPU ID FUNCTION:NAME 1 155 read:entry Google Chrome H
trace
printf
syscall::read:entry{printf(“arg0: %d”, arg0)} !CPU ID FUNCTION:NAME 0 155 read:entry arg0: 7
printf
ustacksyscall::read:entry{ustack()} !CPU ID FUNCTION:NAME 1 155 read:entry libsystem_kernel.dylib`read+0xa CFNetwork`__CFSocketReadWithError(__CFSocket*, unsigned char*, long, CFStreamError*)+0x1e CFNetwork`SocketStream::socketRead(unsigned char*, long, CFStreamError*)+0x1c
Что можно делать
• Анализ приложений и драйверов с применением сложных фильтров
• Профилирование памяти для конкретных объектов
• Профилирование производительности
DEMO
Что не умеет
• вызывать методы и функции пользовательского кода
• обращаться к мемберам объектов
• выводить NSString
• не работает на девайсе
Указатели
printf(“%d”, copyin(arg0, 4));
указатель на int
копирует во временный буфер
С-strings
printf(“%s”, arg0); !
printf(“%s”, copyinstr(arg0));
указатель на c-string
“Фишки” D• автоматическое объявление переменных
• все массивы – ассоциативные
• proc[execname, tid]++
• аггрегации
• @counts["write system calls"] = count();
Стандартные скрипты
• dtruss – эмуляция truss
• iosnoop, iotop – анализ работы с диском
• execsnoop – запуск новых процессов
• man -k dtrace – полный список
Instruments
Дополнительная информация
• man dtrace
• http://www.oracle.com/technetwork/server-storage/solaris10/solaris-dtrace-wp-167895.pdf
• http://docs.oracle.com/cd/E19253-01/817-6223/
• http://www.tablespace.net/quicksheet/dtrace-quickstart.html
• http://www.brendangregg.com/dtrace.html#DTraceToolkit
• http://initwithfunk.com/blog/2013/05/31/breaking-bad-with-dtrace/
• http://www.friday.com/bbum/2008/01/26/objective-c-printing-class-name-from-dtrace/
• http://reverse.put.as/wp-content/uploads/2011/06/Debugging-Cocoa-with-DTrace.pdf