2009-08-19 3 views
1

편집 : 문제가 해결되었습니다. 문제가 실제로 있었던 것처럼 보이지 않는 (또 다른) 상황이었습니다. 단서는 객체에 대한 포인터로 @ 0xfeeefefe를 사용하는 것이 었습니다. 이것은 메모리를 비울 때 Windows API 함수에 의해 반환되는 주소입니다 ... 작동중인 개체가 삭제되었음을 나타냅니다.내 segfault의 소스를 찾는 데 문제가 있습니다.

std :: map에서 값을 지우는 중 세그먼트 오류가 발생하지만 그 이유를 알 수 없습니다.

Program received signal SIGSEGV, Segmentation fault. 
0x0048785f in std::less<irr::gui::IGUIWindow*>::operator()(irr::gui::IGUIWindow* const&, irr::gui::IGUIWindow* const&) const (this=0x258ab04, [email protected], [email protected]) 
at C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_function.h:227 
227   { return __x < __y; } 

하지만 이상한 부분은 두 입력 값의 다음 시험 : 디버거 (GDB)에서 나는 볼

(gdb) x 0x22f778 
0x22f778:  0x025e1ef8 
(gdb) x 0xfeeefefe 
0xfeeefefe:  0x025e1ef8 

일부 배경 : 지도는 포인터에 대한 포인터의 매핑입니다 . 특히, 키는 GUI 시스템의 창에 대한 포인터이며 값은 해당 창에 인쇄 할 정보를 보낼 수있는 객체에 대한 포인터입니다. 디버그 가능 객체와 윈도우의 역 매핑도 있습니다. 그 이유는 윈도우가 닫혀 있으면 디버깅 할 수있는 객체에 정보를 보내서 데이터를 보내려고 시간을 낭비 할 필요가 없기 때문입니다. 역 매핑은 관리자 (이 코드가 속한 클래스)가 디버그 가능 객체에서 패킷을 받으면 정보를 인쇄 할 윈도우를 알 수 있도록합니다.

따라서 두 가지 비교 포인터 값, return(0x025e1ef8 < 0x025e1ef8) 오류가 발생합니까?

필자는 코드 내에서 한 점만 지우려고하며 루프 안에 있지 않으므로 손상시킬 반복기가 없습니다. 나는 또한 다른 장소에있는지도에만 물건을 삽입하고 물건을 넣거나 지울 때 인쇄 한 흔적이 있으며 그 곳에서 아무 것도 볼 수 없습니다.

정말 도움이되는 정보가 충분하지 않지만 코드가 실제로 크기 때문에 문제를 추적하기 위해 무엇을 할 수 있는지 잘 모르겠습니다. 제안이 있으면 더 많은 정보를 제공해 드리겠습니다. 코드의 일부분을 붙여 넣어서 무슨 일이 일어나고 있는지 빠르게 알 수 있습니다. 다행히도 여기에 내 문제가 무엇인지 나타내는 뭔가가 있습니다. 여기

case EGET_ELEMENT_CLOSED: 
{ 
    IGUIWindow* window = 
     static_cast<IGUIWindow*>(event.GUIEvent.Caller); 

    if(m_debugMap.find(window) != m_debugMap.end()) 
    { 
     IGuiDebuggable* debug = m_debugMap[window]; 
     debug->removeListener(this); 

     cout << "closing window: " << window << " attached" 
       " to debuggable: " << debug << endl; 

     m_debugMap.erase(window); /// segfault here 
     m_conMap.erase(debug);  /// if above line commented, segfault here 
    } 

    m_eventMap.erase(window); /// if above block commented, segfault here 
    window->remove(); 
    return true; 
} 

그리고 여기가 당신은 내가 무엇의 주소를 인쇄하고 있습니다 볼 수있는 요소가지도

IGUIElement* winElmnt = 
        m_env->getRootGUIElement()->getElementFromId(0,false); 

IGUIElement* editElmnt = winElmnt->getElementFromId(1); 
IGUIWindow*  window  = static_cast<IGUIWindow*>(winElmnt); 

cout << "CModelTesterGui: adding " << window << "(" << winElmnt 
    << ") to the debug map with edit box " << editElmnt << endl; 

m_conMap[debug]    = static_cast<IGUIEditBox*>(editElmnt); 
m_debugMap[window]   = debug; 

window->setID(-1); 
debug->addListener(this); 

에 추가되는 부분 문제로 부분 들어가고 무엇이지도에서 지워지려고하는지, 그리고 내가 예상하지 못한 것처럼 가치가 없거나 아무 것도 지우려고하지 않는다.

아, 마지막 메모. 이상한 버크가 있습니다. 하나의 창만 열면 (즉,지도에 하나의 요소 만 추가하면) 잘 지울 수 있습니다. 지도에 두 개 이상의 요소를 추가 한 후에 그 중 하나를 지우려고하면 세그멘테이션 오류가 발생합니다.

답변

2

실제로 비교하기 전에 0xfeeefefe을 역 참조하려는 segfault가 발생했습니다. __ x와 __y의 유형은 무엇 해제 힙 메모리 (1)

을 표시하기 위해 마이크로 소프트의 HeapFree()에 의해 사용

FEEEFEEE? __x__y에 기록 된 초기 값을 확인한 다음 메모리 위치에 변경 사항을 기록 할 수 있습니까?

또한 HeapFree 함수에 중단 점을 넣을 수 있으면 잘못된 메모리 참조를 catch 할 수 있습니다.

+0

학습을 필요로하지 않습니다이 문제 그 기능이 정의 된 것 같아 아마도 이름이 망가 졌을 까? 내가 그것을 찾을 수 있는지 보겠다 . – cheshirekow

+0

OMG, 고마워. 내가 필요한 단서 였어. HeapFree에서 흔적을 얻을 수있는 방법을 찾지 못했다. 하지만 일부 힙이 해제되었다고 가정하면 문제가 해결되었다고 가정하므로 클래스가 참조 횟수이므로 removeListener가 소스 객체가 참조를 삭제하도록 유도했지만 ... 클래스가 처음 추가되었을 때 제대로 참조를 포착하지 못했습니다. – cheshirekow

2

아, 마지막주의 사항. 여기 이상한 버크가 있습니다. 하나의 창 (예 : )을 하나만 열면 잘 지울 수 있습니다. 두 개 이상의 요소를지도에 추가 한 후 중 하나를 지우려고하면 세그먼트 화 오류가 발생합니다.

이상한 버크는 일반적으로 메모리 문제를 나타냅니다. valgrind를 실행 해 보셨습니까?

복제를 삽입 하시겠습니까? 지도에서 삽입과 삭제 사이에 포인터가 삭제되고 있습니까?

+0

나는 창문에있어 : ​​15chars :-(/ ... – cheshirekow

+0

이러다 * p를 – Tom

+0

다음 Visual Studio 디버거 – leiz

1

나는 당신의 추적에서 찾고 있어요, 그것은

__x = @ 0x22f778, __y = @ 말한다 어디서보고 있어요 0xfeeefefe 그 __x 및 __y은 참조입니다 제안 할 것

.

그런 경우 테스트를 시도하면 (__x < __y) 참조를 역 참조 할 수 있으며 0xfeeefefe 역 참조는 컴퓨터의 메모리가 설치되어 있지 않으면 좋은 일이 아닐 수 있습니다.

+0

예, Casey의 대답을 참조하십시오. 사용 된 더미 주소 인 것 같습니다. b y win API – cheshirekow

관련 문제