2013-04-23 1 views
2

std::vector이 일부 불량 코드로 덮어 쓰여지고 있습니다. 데이터은 덮어 쓰지 만 내부 상태는 아닙니다. 나는 이것을 알고있다. 왜냐하면 size() 멤버 함수가 프로그램에 정크 값을 반환하기 때문이다. 그것은 올바르게 초기화됩니다. 내 코드의 다른 곳에서 공통 포인터 버그가 의심된다.C++ - lldb/Xcode에서 std :: vector 객체의 주소를 얻는 방법

Xcode 4.6.2입니다. 벡터의 첫 번째 메모리 위치 (벡터 자체가 아닌 데이터)에 메모리 액세스시 하드웨어 중단 점 (lldb)을 설정하여 덮어 쓰는 부분을 볼 수 있습니다. this에 따르면 먼저 벡터의 주소를 찾아야합니다. 일반적으로 & 연산자를 사용하여 변수의 주소를 가져 오지만, lldb를 사용하면 주소를 반환하지 않고 대신 일종의 요약 문자열을 인쇄합니다. 'EXPR'

(lldb) frame variable &myObject.myVector 
(std::vector<double, std::allocator<double> > *) $7 = size=4 

를 같은 결과가 있습니다 :

(lldb) expr &myObject.myVector; 
(std::vector<double, std::allocator<double> > *) $8 = size=4 

은 일반적으로 내가 주소가 인쇄보고 기대를

class myClass { 
public: 
    myClass() : myVector(4) {} 
private: 
    std::vector<double> myVector; 
    double myDouble; 
}; 

모두가 구축 된 후 임의의 중단 점에서 깨는 후 예를 들어 다음과 같은 일반 데이터 멤버 :

(lldb) frame variable &myObject.myDouble 
(double *) &myDouble = 0x0000000125589328 
(대신 4)

(lldb) expr std::vector<double, std::allocator<double> > * f = &myObject.myVector; f 
(std::vector<double, std::allocator<double> > *) $12 = size=0 

제로 크기가 실제로 올바른 벡터를 선택하지 않은 제안이 반환

나는 'expr에'하지만 그 중 하나가 작동하지 않습니다와 변수에 주소를 할당 시도 어쨌든.

어떻게이 벡터의 주소를 얻을 수 있습니까? Xcode의 프레임 변수 목록에서 마우스 오른쪽 버튼을 클릭하고이 벡터의 '메모리보기'를 선택하면 0x0 뷰가 열립니다. 물론 유효하지 않습니다. 벡터는 스택에 할당됩니다. 실제로는 다른 몇 개의 객체 안에 있지만 스택은 모두 생성됩니다.

아니요,은 벡터 내의 데이터 주소를 가져오고 싶습니다. 실제로 덮어 쓰는 것은 아닙니다. 손상되고있는 스택 할당 벡터 객체의 내부 저장소입니다.

+0

디버거에서 볼 수있는 것은 lldb가 도움이되고 사람이 읽을 수 있도록 만드는 것입니다. 그러나 코드에서, 당신은 단지'& myObject.myVector'를 사용할 수 있어야합니다. 'std :: vector * vecPtr = & myObject.myVector; '와 같이 주소를 저장할 변수를 만들 수 있습니다. 그러면 lldb가'vecPtr'로 무엇을하는지 보거나 코드에서 사용할 수 있습니다. – user1118321

+0

나는 그 변수 아이디어를 시도했지만, lldb가 그것을 출력 할 때 그것도 벡터로 포맷한다. 왜냐하면 그것이 벡터에 대한 포인터라는 것을 알고 있기 때문이다. 아마도 나는 '무효'를 사용해야 만했을 것이다. – meowsqueak

답변

7

귀하의 myObject 객체 가능성이 로컬 변수 스택에 존재 :

(lldb) p &myObject 
(myClass *) $0 = 0x00007fff5fbffad8 
(lldb) p $fp >= &myObject && &myObject >= $sp 
(bool) $1 = true 

당신은 lldb이 -R/--raw-output 옵션 frame variable에 사용, 벡터를 꽤 - 인쇄되지하려면 :

(lldb) fr va -R myObject 
(myClass) myObject = { 
    myVector = { 
    std::_Vector_base<double, std::allocator<double> > = { 
     _M_impl = { 
     _M_start = 0x00000001001008d0 
     _M_finish = 0x00000001001008f0 
     _M_end_of_storage = 0x00000001001008f0 
     } 
    } 
    } 
    myDouble = 6.95322297580907e-310 
} 

벡터의 주소가 힙 주소라는 것을 알게 될 것입니다. 즉,안에있는 대신 malloc '(new')이 사용되었습니다.. 이제 모니터링 할 내용을 결정해야합니다.새로운 요소가 벡터의 끝에 추가되고 볼 수있는 벡터를 모니터링 할 경우에, 당신은 당신이 하나의 내용을 모니터링 할 경우,

(lldb) p &myObject.myVector._M_impl._M_finish 
(double **) $4 = 0x00007fff5fbffae0 

을 끝 벡터 포인터를보고 싶어 벡터의 첫 번째는, 당신은 힙의 메모리 영역으로 성장 할 수없는 경우 요소는 (은 새로운 주소 범위로 이동 될 수있는 벡터에 추가 될 때 물론

(lldb) p myObject.myVector._M_impl._M_start 
(double *) $6 = 0x00000001001008d0 

을 모니터링하고 싶은 말은 새로운 요소를 잡으십시오) 그래서 이것은 약간 깨지기 쉬울 것입니다.

일반적으로 lldb의 형식 지정자 (이 경우 std::vector)가 원시 구현을 보는 것이 바람직하지만 원시 구현을 사용하려면이 경우 형식 작성자를 사용하지 않도록 설정하는 것이 더 쉽습니다. 예 :

(lldb) type category disable gnu-libstdc++ 
(lldb) p myObject 
(myClass) $9 = { 
    (std::vector<double, std::allocator<double> >) myVector = { 
    (std::_Vector_base<double, std::allocator<double> >) std::_Vector_base<double, std::allocator<double> > = { 
     (std::_Vector_base<double, std::allocator<double> >::_Vector_impl) _M_impl = { 
     (double *) _M_start = 0x00000001001008d0 
     (double *) _M_finish = 0x00000001001008f0 
     (double *) _M_end_of_storage = 0x00000001001008f0 
     } 
    } 
    } 
    (double) myDouble = 6.95322297580907e-310 
} 

당신은 내장이 type summary list 명령을 lldb하는 타입 포맷터를 모두 볼 수 있습니다.

+0

고맙습니다.'-R'이 열쇠입니다. 이것은'fr va -R & myObject.myVector'를 허용하고 크기 대신에 힙 기반 저장소가 아닌 객체의 벡터 주소를 표시합니다. – meowsqueak

+1

와우. 나는 물건을 배웠다. 감사! –

1

그냥 부록으로, 당신이 말할 수 있었어야 : (lldb) 와치 포인트 집합 식을 & myVector 을 당신이 정말로

또한 값 "을 참조하십시오"할 수없는 경우에도, 당신은 무엇을했다 seeing은 std :: vector에 대한 요약이었습니다 - 우리는 포인터에 적용되지 않거나 값을 보여주기 위해 요약을 지시하지 않는다는 것을 알았습니다.

나는 포인터의 숫자 값을 볼 수있는 오픈 소스 LLDB에 대한 수정을했다. 아마도 실제로 올바른 해결책은 가치 "&"을 보여주는 특별한 "for-pointers"요약 형식이어야합니다. 그러나 나는 LLDB에있는 정규 표현식 포맷터의 양을 복제하기 때문에 그 경로를 지나치게 열정적이지는 않습니다. 이는 성능을 위해 할 수있는 최선의 방법이 아닙니다.

+0

추가 정보 주셔서 감사합니다. – meowsqueak

관련 문제