2011-08-30 6 views
10

나는 this 스레드를 보았습니다. 내 경우는 약간 다르며 나는 "this" 포인터가 어떻게 손상되는지 파악하기 위해 고심하고있다."this"포인터가 스택 추적에서 손상됨

저는 자신의 모델로 QTreeView을 사용하여 Qt 4.6.2 프레임 워크를 사용하고 있습니다. 나는에 전체를 붙여하지 않은 이유를 재귀의 많은 내가 얻는 역 추적 (86 프레임 길이는, 그이 pastebin는 자신의 코드를 포함에 그것의,입니다. 드디어 QBasicAtomicInt 일부 어셈블러에 세그먼테이션 폴트 (segfault)

:: DEREF하지만 그것이 다음 세 개의 프레임으로 더 해졌다 입증되었음을 분명하다 :. 프레임 (17)에

#15 0x01420fd3 in QFrame::event (this=0x942bba0, e=0xbf8eb624) at widgets/qframe.cpp:557 
#16 0x014bb382 in QAbstractScrollArea::viewportEvent (this=0x4, e=0x93f9240) at widgets/qabstractscrollarea.cpp:1036 
#17 0x0156fbd7 in QAbstractItemView::viewportEvent (this=0x942bba0, event=0xbf8eb624) at itemviews/qabstractitemview.cpp:1610 

, this0x942bb0 인 프레임 (16)에 this 프레임 (17)이 부르고 같이 동일해야 그 같은 방법의 조상의 구현입니다. 그러나 this은 0x4가됩니다.

흥미롭게도 프레임 15에서 (다시, 프레임 16은 조상의 동일한 기능의 구현을 호출했습니다) 'this'포인터는 0x942bba0으로 복원됩니다.

전체 백 트레이스의 pastebin을 보면 'value optimized out'을 볼 수 있습니다. 최적화가 적용된 응용 프로그램을 컴파일했습니다. 이제는 gcc가 -g3 -O0으로 설정되었으므로 다음 번에 더 많은 것을 할 수 있습니다. 하지만 물론 지금은 충돌을 일으킬 수 없습니다. 너무 의심스러운 일이 아니기 때문에 매우 어려운 버그가 발생합니다 (그러나 그럼에도 불구하고 수정하는 것이 중요합니다).

최적화가 주어진 경우 thispointer=0x4이 비정상입니까 아니면 틀린가요? 이상한 점은이 viewportEvent 프레임에 실제 코드가 없다는 것입니다. 이벤트 유형에 대한 전환 만 수행하면 switch 문을 통해 빠져 나오고 조상의 구현을 반환합니다.

Valgrind는 Valgrind에서 아직 충돌을 일으키지 않았지만 모든 문제를 던지고있는 것 같지 않습니다.

이전에이 동작을 본 사람이 있습니까? 무엇 때문에 그 원인이 될 수 있습니까?

+1

+1, 오랫동안 나는 나의 코드에서 같은 문제를 보았다. 나는 그것을 어떻게 고쳤는지 모른다. 그러나 나는 옛날을 생각 나게한다.:) – iammilind

+0

코드를 컴파일 할 때 경고가 나타 납니까? 먼저 수정하십시오. –

+0

@ iammilind : 이것은 별을 클릭하여 좋아하는 질문을하는 이유입니다.하지만 투표를 높이는 이유는 아닙니다. –

답변

8

최적화 된 빌드를 디버깅 할 때 이전에 이런 종류의 것을 보았지만 실제 버그가 무엇인지 표시하지 못했습니다.

로컬 변수에 대해 먼저 생각하는 것이 더 쉽습니다. 최적화되지 않은 빌드에서는 모든 것이 메모리에 지정된 위치를 가지며 모든 코드 행 다음에 저장해야합니다. 이것은 디버거가 찾을 수 있도록하는 것입니다. 최적화 된 빌드에서 값은 메모리에 기록되지 않고 레지스터에 살 수 있습니다. 이것은 최적화 된 빌드의 향상된 성능의 주요 부분입니다. 디버거는 이것을 이해하지 못하며 항상 메모리를 볼 것이므로 잘못된 값을 자주 볼 수 있습니다.

매개 변수에서도 마찬가지 일 수 있습니다. 옵티마이 저가 레지스터에 매개 변수를 전달하기로 결정하면 디버거는 여전히 스택 프레임을 살펴볼 것입니다. 보다 구체적으로, 매개 변수가 호출 규칙의 규칙에 따라 위치하는 위치에 있습니다.

스택의 다음 프레임에 값이 올바르게 복원되었다는 사실은 생성 된 명령어가이 매개 변수를 올바르게 처리하지만 디버거에서 어디에서 찾을 지 알 수 없음을 나타냅니다.

+0

또 다른 변형은 매개 변수가 스택에 전달 되더라도 옵티마이 저는 매개 변수의 위치를 ​​사용하여 완료되면 메모리 위치를 다른 용도로 재사용 할 수 있습니다. backtrace에서'this pointer = 0x4'가 빨간 청어 일 가능성이 있습니다. 특히'this' 포인터 매개 변수가 더 낮은 번호의 프레임에 올바르게 나타나면 가능합니다. –

+0

응답 해 주셔서 감사합니다. 이제 최적화 기능을 사용할 수 없게되었습니다. 다시 충돌을 시도하기 위해 열심히 노력하고 있습니다. 특히 트리 뷰에서 드래그 앤 드롭 중에 발생합니다. 특히 손가락 압력을 해제 할 때 터치 스크린이 재미있는 위치에있을 때 그렇습니다. 자동화하기 쉽다! 처음에는 재현하기가 어렵습니다. 다행히 최적화되지 않은 코어 덤프가 좀 더 유용한 결과를 보여줍니다. 흥미 롭 군. 따라서 이론적으로 볼 때 코어 덤프에서 어셈블러를 검사하고 레지스터를 살펴보면 '이것이'무엇이되어야 하는지를 알 수 있습니다.하지만 아마도 도움이되지 않을 것입니다. – xwhatsit