매력적인 Xcode 디버깅 팁ARC, Instruments, DTrace
twitter.com/@godrmOSXDEV.org오로라플래닛 김정
Single Window
Built-in Interface Builder
LLVM Compiler
LLDB Debugger
Fix-it & Live issueAssistant
Version Editor
Navigators & Utilities
Multi-window & Multi-tab
Visual Connections (IB)
Refactor
Code Complete
New Instruments
Scheme
Workspace
Debugging
이미지 출처: http://www.dumpanalysis.org/debugging-story-annual-competition
Debugging Tip#1Breakpoint action
Breakpoint Action
✴ Condition (조건)
✴ Ignore (무시할 반복회수)
✴ Action (동작)
✴ AppleScript, Capture OpenGL ES Frame, Debugger Command, Log Message, Shell Command, Sound
✴ Options (선택사항)
Exception Breakpoint
✴ 프로젝트 전체 범위
✴ 예외(Exception) 발생할 경우
✴ C++ / Objective-C 형태 예외처리
✴ 동작 설정 가능
Symbolic Breakpoint
✴ 소스 코드의 심벌 이름에 설정
✴ [클래스 +] 메서드 형태 심벌 지정
✴ 모듈 (라이브러리) 지정
LLVM
osxdev.org
Introduction• LLVM
- Low-Level Virtual Machine• An Infrastructure for Multi-stage Optimization
- by Chris Arthur Lattner @2002• Design and Implementation of a compiler infrastructure
- support a unique multi-stage optimization system- support inter-procedural and profile-driven optimizations
• LLVM virtual instruction (IR)- with high-level type information
• Sponsored by APPLE
osxdev.org
Compiler ArchitecturesGCC#4.2#
프론트엔드#
C"Tree*SSA#최적화기# 코드 생성기#C++"
Objec)ve+C"실행파일"
GCC"4.2"
GCC#4.2#프론트엔드#
C"LLVM#
최적화기#LLVM#
코드 생성기#C++"
Objec)ve+C"실행파일"
LLVM+GCC"4.2"
Clang#프론트엔드#
C"LLVM#
최적화기#LLVM#
코드 생성기#C++"
Objec)ve+C"실행파일"
LLVM"
osxdev.org
Effective LLVM ProjectsXcode
OpenCL
OpenGL Optimize(speed)
Optimize(size)
DynamicProg.
Clang
LLDB LLVM
Debugging Tip#2Static Analysis
osxdev.org
잘못된 예제 코드CFNumberRef CFNumberError(int param){ unsigned int i = 1; bool isWork = NO; CFNumberRef x = CFNumberCreate(0, kCFNumberLongType, &i); if (param==0) isWork = YES; return x;}
void leakError(){ NSMutableString *aString = [NSMutableString stringWithCapacity:100]; [aString retain]; //... NSMutableArray *aArray = [[NSMutableArray alloc] initWithCapacity:10]; //... [aArray removeAllObjects]; //release}
void NullDerefence(id object){ char* pChar = NULL; ///pChar pointer... *pChar = '!';}
int uninitialized(int x){ int result; if (x>0) { result = 1; } else if (x==0) { result = 0; } return result;}
잘못된 사용 (API Misuse)
죽은 코드 (Dead store)
죽은 코드 (Dead store)
잠재된 메모리 누수 (Potential Leak)
널 참조 (Null Dereference)
논리적 오류 (Logic Error)
Debugging Tip#3ARC vs no-ARC
osxdev.org
ARC• Automatic Reference Counting
- Automatic memory management of Objective-C objects- Just Compile-time, Not Run-time
• Not Garbage-Collector• Migration Tool in Xcode 4.2
- with LLVM 3.0- build-settings : -fobjc-arc (cf. -fno-objc-arc)
• New Rules- remove dealloc, retain/release/autorelease
✴ can still use CFRetain / CFRelease in CF
- Can’t use NSAllocateObject / NSDeallocateObject- Can’t use object pointer in C Structures- no casual casting id -> void*- Can’t use NSAutoreleasePool -> @autoreleasepool- Can’t use memory zone (NSZone)- Can’t give a property name with new-
Automatic Reference Counting
Debugging Tip#4Diagnostics
osxdev.org
Diagnostics• Memory Management
- Malloc ✴ Enable Scribble✴ Enable Guard Edges
- Guard Malloc- Objective-C - Zombie Objects
• Logging- Memory
✴ Distributed Objects✴ Garbage Collection Activity✴ Malloc Stack
- Exception- Dyld API Usage- Library Loads
• Debugger- Stop on Debugger() and DebugStr()
osxdev.org
LLDB• Next-generation• & High-performance Debugger• a set of reusable components in LLVM
• Clang expression parser• LLVM disassembler
• C/C++, Objective-C• Efficient Multi-threading, symbol manager• Extension - Python script• Support Remote protocol/debug server
osxdev.org
IntroductionGDB
LLDB
% gdb a.out(gdb) break mainBreakpoint 1 at 0x100000f33:file main.c line4(gdb) run
% lldb a.out(lldb) breakpoint set --name mainBreakpoint created:1:name=‘main’, locations=1(lldb) process launch
osxdev.org
IntroductionGDB
LLDB
(gdb) info argsargc = 1argv = (const char **) 0x7fff5fbff550(gdb) info localsi = 32767
(lldb) frame variableargc = 1argv = 0x00007fff5fbfff68i = 0
osxdev.org
LLDB Command Syntax
Command Syntax<type> <action> [-options [option-value]] [argument [argument...]]
Uses standard getopt_long() for predicate behavior(lldb) process launch a.out --stop-at-entry (lldb) process launch a.out -- --arg0 --arg1(lldb) process launch a.out -st
Options know which other options they are compatible with(lldb) process attach --pid 123 --name a.out
Type : breakpoint, commands, frame, image, log, memory, process, regexp-break, register, settings, source, target, thread
osxdev.org
Common CommandsGDB LLDB
(gdb) ^C(gdb) signal 2(gdb) info break(gdb) continue(gdb) step(gdb) stepi(gdb) next(gdb) nexti(gdb) finish(gdb) info threads(gdb) backtrace
(lldb) process interrupt(lldb) process signal SIGINT(lldb) breakpoint list(lldb) process continue(lldb) thread step-in(lldb) thread step-inst(lldb) thread step-over(lldb) thread step-over-inst(lldb) thread step-out(lldb) thread list(lldb) thread backtrace
osxdev.org
Common CommandsGDB LLDB
(gdb) ^C(gdb) signal 2(gdb) in br(gdb) c(gdb) s(gdb) si(gdb) n(gdb) ni(gdb) f(gdb) info threads(gdb) bt
(lldb) pro int(lldb) pro s SIGINT(lldb) br l(lldb) c(lldb) s(lldb) si(lldb) n(lldb) ni(lldb) f(lldb) th l(lldb) bt
osxdev.org
Apropos Command(lldb) apropos thread
The following commands may relate to 'thread':breakporint command add -- Add a set of commands to a breakpoint, to be executed whenever ...breakpoint modify -- Modify the options on a breakpoint or set of breakpoints...breakpoint set -- Sets a breakpoint or set of breakpoints in the executable.frame -- A set of commands for operating on the current thread's...frame info -- List information about the currently selected frame in the...frame select -- Select a frame by index from within the current thread...log enable -- Enable logging for a single log channel.process continue -- Continue execution of all threads in the current process.register -- A set of commands to access thread registers.thread -- A set of commands for operating on one or more... thread backtrace -- Show the stack for one or more threads. If no threads are... thread continue -- Continue execution of one or more threads in an active... thread list -- Show a summary of all current threads in a process. thread select -- Select a thread as the currently active thread.thread step-in -- Source level single step in specified thread (current... thread step-inst -- Single step one instruction in specified thread (current..
osxdev.org
Expression in LLDBLLDB
(lldb) expression x+y->getCount() (int) $0 = 2(lldb) expression pt(struct point_tag) $1 = { (int) x = 2 (int) y = 3}(lldb) expression $1.x(int) $2 = 2
osxdev.org
References
• Apple Documents - Technical Notes
• TN2124 Mac OS X Debugging Magic• https://developer.apple.com/library/ios/#technotes/tn2004/
tn2124.html#//apple_ref/doc/uid/DTS10003391
• TN2239 iOS Debugging Magic• https://developer.apple.com/library/ios/#technotes/tn2239/
_index.html#//apple_ref/doc/uid/DTS40010638
InstrumentsXray
새로워진 Instruments #1
✴ The Jump Bar✴ Improved View Access
✴ Collapsible, Track, Full screen✴ The Call Tree✴ Backtrace Compression with Filtering✴ The Source View✴ Timeline Flags
- Navigating the improved UI
새로워진 Instruments #2
✴ Immediate vs. Deferred Mode✴ Immediate mode - “Classic Instruments mode”✴ Deferred mode
✴ Processes and displays data at end of recording✴ Vastly reduces “observer effect” ✴ More samples relate to your app.
✴ Launch Daemons and Agents (Mac OS X only)✴ over Wi-Fi (iPhone OS 3.1+)✴ Re-Symbolication
- Recording Techniques
새로워진 Instruments #3
✴ Time Profiler✴ more efficient than CPU Sampler✴ Deferred mode
✴ Heapshots✴ Part of Allocation template
✴ VM Tracker✴ Tracks the virtual memory of a process
- Advancement to existing Instruments
새로워진 Instruments #4
✴ Energy Diagnostics✴ Provides diagnostics regarding energy usage✴ Records battery power and CPU usage
✴ Automation✴ Simulate UI interaction with iOS app.✴ Leverages JavaScript to script iPhone UI
components✴ OpenGL ES Analysis
- Significant New Instrumentation
UI Automation
✴ Automates UIKit based applications✴ Touch based✴ iPhone, iPod touch and iPhone Simulator✴ Integrated in Instruments✴ Accessibility based✴ JavaScript automation scripts✴ UI Automation Reference Collection
- What is this?
새로워진 Instruments #4
✴ System Trace✴ Provides comprehensive information on system
behavior✴ Identifies when threads are scheduled and why✴ Display thread transition from user space into
system code✴ System calls, VM operations
✴ Highlights View - summary
- Really New Instrumentation
DTrace$ D Language
Software Stack Tools
DTrace is...✴ dynamic tracing facility✴ developed by Sun Microsystems
✴ for Solaris 10✴ designed by Bryan Cantrill, Mike Shapiro, and Adam
Leventhal.
✴ introduced with Leopard (Prior to 10.5 ktrace)
✴ http://hub.opensolaris.org/bin/view/Community+Group+dtrace/WebHome
✴ http://en.wikipedia.org/wiki/DTrace
osxdev.org
Overviewptg6843614
��%
J�����
�*�����$���������������)����������%����������(+������$�$�� $�)������(����$���������$�$�� "��*�������$��� ���$����$�������%�����$��<���������$�$�� �����+���$�������,����,�$"!�������������+�������,������ ��+�$�������)� ���������� $"��*����,�$������+����,������F@(FDF��"."�&��������". ��������$�%�����$� ��� ��+�� ����� ���� ��+��$�"
�������%*���������)��*�����$��������)�#�,������������$����� �������������<��+���������"�*�����������$���$�����������������%���$ �)+�����������$ �@�?����%���� �$$����$���$ �$�$�� �����$ ����� �������������$������%���$ ��$�$��,�����-��+�F7"�"����F@(FD�����+��$����$��)����+$���$��)�����$ ����������+�����,$�,�����������,�@(�����$�"�V�+�������������$������+��,�������������$�����������$�������������)�������������+����������������$��)���+��,������"
�������0��;;8����� ��1�#
&���$�������� ���������$������$��������,������+�+������<��� ���"�*�����$����� �����������$�$�� ��)�����$��������������������+$��������$�+ ����������$��� ������������ ��"�*��$� ��$�*����$�)�����+$����������+������$�$�� ����������$��+��� ������� $"�&���$����� ��� �����$� ���������#&;�4#�����������;������5��� ��(&������� �,����$� ��$�������)�������$���)� ��
osxdev.org
DTrace Workflow
ptg6843614
:�� ����0;;8����
��&
��� �����)+��������������������))���������������������������)�$��)�,���$�+�����$��)�����)+������"*���)�� �������$������$�+ ����������������$����)��������%������$����������)� ���������������,��������+$�����*���"�#�������$�����+�� �����������$�������������+��*�����<��� �������$"&���$�����)��������+���� �$����+�����+�� +��������<��� ���$�����������"
2������������,������%������������$"�-���<� ��� ���������������%��������,$�����$����������������$�$�� �����$"�*������ ������%���������$�����$������+����� ������%��$"
*����� �����������������������������$���+�����,�����������)��*���T$�)���+�$"�!��������$����������$�%�������������+ �����������������)����)����,�����$���+�,�$��������������+����� ����������$�$�� ����%��"��+��������������������$�����$������������������������$��������������������$���������+��������������"
V�+�����+$������$���������������<��$��$���%���������)���+��,����$���"�*���������$���+��$$������,�������������������+�������������$�������� ��������������� ��$�� � ��<� ������������+ ��������)+������ ����<� ������������+��%��+��)� ���)+������"�*�+$ ��������,�����������������$��$��$���� �����$��$�$�$�����������+���+������$�$�� "�V�+��������������������������)�����$��$�$��������C��$�$�� �����%���"�*����*����L,�)��,M��$�$��,�����-��+�F7"� �,������$�����������)����������� �������+������������� ����+ +����������� ������%���+���������������������������+$�"
�������0��;;8�����5��.'!�5
�����&���"���#�����$����,������+$��������L�M����� ��������+���"����$������������$������������+��� ����$�� ������,������$����%������)�+����������"�#������$+�$����)����$�$+�������������,������$�������$��
osxdev.org
D Language✴ A Large subset of C✴ with a special set of functions to analyzing system
behavior.✴ run in kernel-land.
✴ compiled into a safe form (similar to java bytecode)
✴ validated for safety.
✴ filename extension .d
DTraceToolkit
osxdev.org
DTraceTookits✴ iosnoop✴ hfssnoop✴ execsnoop✴ opensnoop✴ dtruss✴ soconnect_mac✴ errinfo✴ bitesize✴ iotop✴ maclife
Probes
osxdev.org
Probes
✴ Providers - the instruments
✴ Module - a specific program location
✴ Function - a specific function name
✴ Name - an indication of the probe’s semantic meaning
syscall :: open : entrysyscall :: open* : entrysyscall ::: entrysyscall :::
osxdev.org
BEGIN - END Providers/* show the BEGIN and END providers run with: sudo dtrace -s begin-end.d*/
BEGIN{ trace("begin the beguine"); exit(0);}END{ trace("that's all, folks...");}
osxdev.org
syscall Provider/* show all system calls being made, system-wide Run with sudo dtrace -qs syscalls.d*/syscall:::/execname != "dtrace"/{ printf("%s fired in %s", probefunc, execname);}
osxdev.org
profile Provider/* show the profile (timer) provider. Run with sudo dtrace -s lubdub.d*/profile:::tick-5sec{ trace("five second timer");}profile:::tick-1min{ trace("one minute timer");}profile:::tick-800msec{ trace("800 millisecond timer");}
osxdev.org
proc Provider/* Show procoess launches across the system. Run with sudo dtrace -s execs.d*/proc:::exec-success{ trace(execname);}
osxdev.org
Actions
✴ the lines of code
✴ assign values to variables, perform computations, aggregate values over time...
✴ no flow control (no if, no loops)
✴ use predicates
osxdev.org
Variables
✴ C standard types : char, int, short, long, long long...
✴ display floating point values from probes
✴ cannot perform floating point math
✴ cannot cast float to integer
✴ global by default
✴ standard C operators all work
✴ do comparison operators (^^ XOR)
✴ use strcmp()
osxdev.org
example 9.6/* sings a pretty song. run with: sudo dtrace -qs beer.d*/int bottles; /* optional */BEGIN{ bottles = 99;}profile:::tick-1sec{ printf("%d bottles of beer on the wall\n", bottles); printf("%d bottles of beer.\n", bottles); printf("take one down, pass it around\n"); printf("%d bottles of beer on the wall\n\n", bottles); bottles--;}END{ printf("that's all, folks...");}
osxdev.org
Scoped Variables
✴ Thread-local variable = self->
✴ Clause-local variable = this->
osxdev.org
Built-in Variables✴ int64_t arg0, arg1, ... arg9✴ args[]✴ cwd✴ errno✴ execname✴ pid✴ stackdepth✴ timestamp, vtimestamp✴ probeprov, probemod✴ probefunc, probename
osxdev.org
example 9.7/* show all system calls being made, system-wide Run with sudo dtrace -qs syscalls.d*/syscall:::/execname != "dtrace"/{ printf("%s fired in %s", probefunc, execname);}
osxdev.org
Functions
✴ printf
✴ trace
✴ printa
✴ ustack
✴ exit
✴ copyin, copyinstr
osxdev.org
Arrays
/* calculate the wall-clock time it takes to read() Run with sudo dtrace -qs ./readtime.d*/syscall::read:entry{ ts[pid, probefunc] = timestamp;}syscall::read:return/ts[pid, probefunc] != 0/{ delta = timestamp - ts[pid, probefunc]; printf("read in %s took %d nsecs", execname, delta);}
osxdev.org
Predicates
✴ logical expressions
✴ enclosed by slashes
/* Watch entry into kevent() */syscall::kevent:entry/execname == "dirwatcher" || execname == "DirectoryServic"/{ printf("%s called kevent()", execname);}
osxdev.org
Aggregates
✴ count()
✴ sum(expression)
✴ avg(expression)
✴ min(expression)
✴ max(expression)
✴ quantize(expression)
@name[key] = aggfunc()
DTrace Reference Book
ptg
http://www.dtracebook.com/index.php/Main_Page