gdb로 표준 컨테이너 (std :: map) 내용 검사


93

다음과 같은 것을 가정합니다.

#include <map>
int main(){
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;
}

gdb에서 프로그램을 실행하는 맵의 내용을 검사하고 싶습니다.
아래 첨자 연산자를 사용하면 다음과 같은 결과가 나타납니다.

(gdb) p m[1]
Attempt to take address of value not located in memory.

find 메서드를 사용하면 더 나은 결과를 얻을 수 없습니다.

(gdb) p m.find(1)
Cannot evaluate function -- may be inlined

이를 수행하는 방법이 있습니까?


큰 맵을 자르지 않고 모든 요소를 ​​인쇄하려면 : stackoverflow.com/questions/47743215/… "인라인 된 기능을 평가할 수 없음"에 중점을 둡니다. stackoverflow.com/questions/40633787/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

답변:


35

적어도 소스가 최적화 된 경우에는 그렇지 않다고 생각합니다. 그러나 STL 컨테이너를 검사 할 수있는 gdb 용 매크로가 있습니다.

http://sourceware.org/ml/gdb/2008-02/msg00064.html

근데 이거 안쓰니까 YMMV


1
링크 주셔서 감사합니다. 유일한 것은 매크로가 stl 라이브러리 버전에 의존한다는 것입니다. +1
Paolo Tedesco

"plist foo std :: string"과 같은 명령이 구문 오류를 제공한다는 점도 약간 실망 스럽습니다. value_type에 구두점이 포함될 수없는 것 같습니다.
Bklyn

2
나는 시도하지 않았지만 이것이 GDB의 나머지 부분과 동일하게 작동한다면 이름을 작은 따옴표로 묶어서 이름을 묶어야합니다.
jpalecek

2
참고 :이 스크립트의 std :: map 기능은 32 비트 포인터 유형을 가정합니다. 64 비트 컴퓨터의 경우 파일의 모든 위치에서 "+ 4"를 "+ 8"로 바꿉니다.
Kyle Simek

pvector가 내 gdb (버전 7.5.91.20130417-cvs-ubuntu)에 정의되어 있지 않습니다.
Jeff

92

이 질문에 대한 기존 답변은 매우 오래되었습니다. 최신 GCC 및 GDB 에서는 GDB 7.x에 내장 된 Python 지원 및 GCC와 함께 제공되는 libstdc ++ pretty 프린터 덕분에 Just Works TM 를 사용할 수 있습니다.

OP의 예에서는 다음을 얻습니다.

(gdb) print m
$1 = std::map with 2 elements = {[1] = 2, [2] = 4}

자동으로 작동하지 않으면 GDB 위키 의 STL 지원 페이지 에서 첫 번째 글 머리 기호를 참조하십시오 .

자신의 유형에 맞는 Python 예쁜 프린터를 작성할 수도 있습니다. GDB 매뉴얼의 Pretty Printing 을 참조하십시오 .


2
예,하지만 다른 질문이 중복되어 닫히고 있으므로 최근 정보를 갖고 싶었습니다.
조나단 Wakely

1
나는 GDB 7.2를 사용하고 있으며 위의 작품은 ... 작은 컬렉션이 있다면. STL 구현의 내부 구조를 사용하는 것 외에는 4K 벡터에서 1543이라고 말한 요소를 인쇄하는 방법을 아직 찾지 못했습니다.
pavon

5
예, GDB 7.2 및 icpc 컴파일러에서 오류가 발생 Could not find operator[]합니다.
pavon

11
불행히도 모든 배포판에서 "Just Work"가 아닙니다. Ubuntu 13.10에는 기본적으로 설치되지 않으며 수동으로 설치하려고 할 때 문제가 있습니다
nietaki

1
@razeh, Fedora, RHEL (및 RHEL 클론). GDB는 파이썬 3에 연결되는 경우 프린터는 배포판에서 작동하도록 진행중인 수정있다
조나단 Wakely

25

항상 명백한 것이 있습니다. 자신의 테스트 기능을 정의하십시오 ... gdb에서 호출하십시오. 예 :

#define SHOW(X) cout << # X " = " << (X) << endl

void testPrint( map<int,int> & m, int i )
{
  SHOW( m[i] );
  SHOW( m.find(i)->first );
}

int
main()
{
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;  // Line 15.
}

과:

....
Breakpoint 1 at 0x400e08: file foo.C, line 15.
(gdb) run
Starting program: /tmp/z/qD 

Breakpoint 1, main () at qD.C:15
(gdb) call testPrint( m, 2)
m[i] = 4
(*m.find(i)).first = 2
(gdb) 

16
프로세스가 실행되는 한. 코어 덤프에는 그다지 유용하지 않습니다.
숀 라일리

2
이것은 STL뿐만 아니라 일반적으로 GDB를 디버그하는 유용한 조언입니다. 검색하기 어려운 많은 데이터 (예 : write_cuda_array_as_image ())를 위해 gdb 도우미 함수의 전체 라이브러리를 유지합니다. 일부 컴파일러는 호출되지 않은 모든 함수를 제거하므로 메인의 "return 0;"다음에 각 도우미 함수를 호출합니다. 또한 extern "C"로 선언하면 gdb에서 쉽게 호출 할 수 있습니다.
Kyle Simek

21

stl-views.gdb하지만 더 이상, 거기에 있었던 가장 좋은 대답이 될하는 데 사용됩니다.

GDB아직 메인 라인에 통합되어 있지는 않지만, 'archer-tromey-python' 브랜치를 사용하여 얻은 결과는 다음과 같습니다.

(gdb) list
1   #include <map>
2   int main(){
3       std::map<int,int> m;
4       m[1] = 2;
5       m[2] = 4;
6       return 0;
7   }
(gdb) break 6
Breakpoint 1 at 0x8048274: file map.cc, line 6.
(gdb) run

Breakpoint 1, main () at map.cc:6
6       return 0;
(gdb) print m
$1 = std::map with 2 elements = {
  [1] = 2,
  [2] = 4
}
(gdb) quit

12

De-Referencing STL Containers : on this page : http://www.yolinux.com/TUTORIALS/GDB-Commands.html


이것들은 비즈니스로 보입니다!
Richard Corden

실제로 이전 답변과 동일한 매크로입니다. :) 더 간단한 해결책이 없습니다.
Paolo Tedesco

명령은 무엇입니까? 당신은 많은 양의 무관 한 정보를 가지고 우리를 오프 사이트에서 운영 할 수있었습니다. 나는 "GDB를 시작하는 방법"과 다른 것들에 관심이 없습니다.
jww

1

위의 답변은 작동하고 괜찮습니다. stl-views.gdb를 사용하는 경우 여기에 포함 된 맵과 요소를 보는 적절한 방법이 있습니다. 지도는 다음과 같습니다. std::map<char, int> myMap;

(gdb) pmap myMap char int

pmap <variable_name> <left_element_type> <right_element_type>,지도의 요소를 볼 수 있습니다.

도움이되기를 바랍니다.


0

두 번째 문제 ( Cannot evaluate function -- may be inlined)는 프로그램을 컴파일 할 때 컴파일러가 DWARF-2 (또는 3 또는 4) 디버깅 정보를 사용하는지 확인하여 해결할 수 있습니다 . DWARF-2에는 인라인 정보가 포함되어 있으므로 설명한 방법 중 하나를 사용하여 std::map컨테이너의 요소에 액세스 할 수 있어야합니다 .

DWARF-2 디버그 정보로 컴파일하려면 컴파일 -gdwarf-2명령어에 플래그를 추가 하세요.


1
음, 함수가 인라인 된 위치를 알면 GDB가 해당 함수에 대한 호출을 평가할 수 없습니다. GDB는 실제로 함수의 라인 외부 복사본에 액세스해야합니다!
SamB
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.