Objective-C를 debug할 때 다음과 같이 break point(이하 bp)를 지정할 수 있습니다.
b -[UIViewController setInterfaceOrientation:]
이렇게 지정한 뒤 실행하면 다음과 같이 중지됩니다.
bt 명령을 이용하면 call stack를 볼 수 있습니다.
#0은 현재 bp 된 위치를 나타내며, bp를 걸었던 UIViewController setInterfaceOrientation: 에서 멈춰있는 것을 볼 수 있습니다.
보통 call stack은 main()부터 시작하며, #<번호> 부분으로 이동하기 위해서는 frame 명령어를 사용합니다. 예를 들어 "#1 -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]" 부분으로 이동하기 위해서는 "frame 1"과 같이 입력합니다. 또는, 현재 위치를 기준으로 +1 되어 있으므로 "up 1"를 입력하여도 됩니다.
"frame 1"로 입력하였을 경우 다음과 같이 현재 위치가 변경됩니다.
이 상태에서 인자를 보고 싶을 때 일반 c application은 인자들이 목록에 나와서 display 명령어로 볼 수 있습니다.
이 때 주의할 점은 $ebp레지스터를 이용하기 때문에, 다른 frame의 값은 볼 수 없다는 것 입니다.
위와 같이 0 frame으로 변경한 뒤, setInterfaceOrientation:의 첫번째 인자를 보면 1로 표시됩니다.
$ebp는 함수 시작 시 설정되는($esp가 저장되어) stack의 시작 주소 이기 때문에 (int *)로 캐스팅 한 뒤 역참조 연산자인 *를 붙여서 정수 값을 출력 하였습니다.
일반 c 프로그램을 디버깅 할 때는 display가 유용하지만 Objective-C에서는 다른 방법으로 봐야 합니다. (display로 봐도 되긴 합니다)
display를 이용하면 다음과 같이 나옵니다.
무엇인가 po가 더 간단해보이죠??? (장, 단점이 있습니다)
디버깅을 Xcode가 다 해준다지만.. 그래도 gdb 정도는 쓸 수 있어야겠죠???
Pending breakpoint 1 - "-[UIViewController setInterfaceOrientation:]" resolved (gdb)
bt 명령을 이용하면 call stack를 볼 수 있습니다.
#0 0x3097263a in -[UIViewController setInterfaceOrientation:] () #1 0x30978386 in -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:] () #2 0x309221fb in -[UIView(Internal) _didMoveFromWindow:toWindow:] () #3 0x30920883 in -[UIView(Hierarchy) _postMovedFromSuperview:] () #4 0x3092079e in -[UIView(Internal) _addSubview:positioned:relativeTo:] () #5 0x3091a113 in -[UIView(Hierarchy) addSubview:] () ......... (gdb)
#0은 현재 bp 된 위치를 나타내며, bp를 걸었던 UIViewController setInterfaceOrientation: 에서 멈춰있는 것을 볼 수 있습니다.
보통 call stack은 main()부터 시작하며, #<번호> 부분으로 이동하기 위해서는 frame 명령어를 사용합니다. 예를 들어 "#1 -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]" 부분으로 이동하기 위해서는 "frame 1"과 같이 입력합니다. 또는, 현재 위치를 기준으로 +1 되어 있으므로 "up 1"를 입력하여도 됩니다.
"frame 1"로 입력하였을 경우 다음과 같이 현재 위치가 변경됩니다.
(gdb) frame 1 #1 0x30978386 in -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:] () (gdb)
이 상태에서 인자를 보고 싶을 때 일반 c application은 인자들이 목록에 나와서 display 명령어로 볼 수 있습니다.
이 때 주의할 점은 $ebp레지스터를 이용하기 때문에, 다른 frame의 값은 볼 수 없다는 것 입니다.
(gdb) frame 0 #0 0x3097263a in -[UIViewController setInterfaceOrientation:] () (gdb) display *(int *)($ebp + 16) 1: *(int *) ($ebp + 16) = 1 (gdb)
위와 같이 0 frame으로 변경한 뒤, setInterfaceOrientation:의 첫번째 인자를 보면 1로 표시됩니다.
$ebp는 함수 시작 시 설정되는($esp가 저장되어) stack의 시작 주소 이기 때문에 (int *)로 캐스팅 한 뒤 역참조 연산자인 *를 붙여서 정수 값을 출력 하였습니다.
일반 c 프로그램을 디버깅 할 때는 display가 유용하지만 Objective-C에서는 다른 방법으로 봐야 합니다. (display로 봐도 되긴 합니다)
(gdb) po _rootView <UIView: 0xd1a650; frame = (0 0; 320 480); layer = <CALayer: 0xd1a680>> (gdb)
display를 이용하면 다음과 같이 나옵니다.
(gdb) display _rootView
1: self->_rootView = (UIView *) 0xd1a650
(gdb) display *_rootView
2: *self->_rootView = {
<UIResponder> = {
<NSObject> = {
isa = 0x31a5c620
}, <No data fields>},
members of UIView:
_layer = 0xd1a680,
_tapInfo = 0x0,
_gestureInfo = 0x0,
_gestureRecognizers = 0x0,
_charge = 0,
_tag = 0,
_viewFlags = {
userInteractionDisabled = 0,
implementsDrawRect = 0,
implementsDidScroll = 0,
implementsMouseTracking = 0,
hasBackgroundColor = 0,
isOpaque = 1,
becomeFirstResponderWhenCapable = 0,
interceptMouseEvent = 0,
deallocating = 0,
debugFlash = 0,
debugSkippedSetNeedsDisplay = 0,
debugScheduledDisplayIsRequired = 0,
isInAWindow = 0,
isAncestorOfFirstResponder = 0,
dontAutoresizeSubviews = 0,
autoresizeMask = 0,
patternBackground = 0,
fixedBackgroundPattern = 0,
dontAnimate = 0,
superLayerIsView = 0,
layerKitPatternDrawing = 0,
multipleTouchEnabled = 0,
exclusiveTouch = 0,
hasViewController = 0,
needsDidAppearOrDisappear = 0,
gesturesEnabled = 1,
capturesDescendantTouches = 1,
deliversTouchesForGesturesToSuperview = 1,
chargeEnabled = 0,
skipsSubviewEnumeration = 0
}
}
(gdb)무엇인가 po가 더 간단해보이죠??? (장, 단점이 있습니다)
디버깅을 Xcode가 다 해준다지만.. 그래도 gdb 정도는 쓸 수 있어야겠죠???



Attribution/Share Alike 2.0 license






