디버깅 헬퍼
Qt Creator 는 파이썬 스크립트를 사용하여 디버거 백엔드(현재 GDB, LLDB 및 CDB가 지원됨)의 원시 메모리 콘텐츠와 유형 정보 데이터를 로컬 및 표현식 보기에서 사용자에게 표시되는 형식으로 변환합니다.
GDB의 예쁜 프린터 및 LLDB의 데이터 포맷터와 달리 Qt Creator 의 디버깅 헬퍼는 기본 디버깅 백엔드와 독립적입니다. 즉, 동일한 코드를 Linux의 GDB, macOS의 LLDB, Windows의 CDB 또는 지원되는 세 가지 백엔드 중 하나 이상을 사용할 수 있는 다른 모든 플랫폼에서 사용할 수 있습니다.
시스템에 설치되어 있거나 애플리케이션에서 사용하는 라이브러리에 연결된 기본 GDB 예쁜 프린터를 사용하려면 환경설정 > Debugger > GDB > Load system GDB pretty printers 로 이동하세요. 자세한 내용은 GDB를 참조하세요.

기본 제공 디버깅 헬퍼 사용자 지정하기
기본 제공 디버깅 헬퍼가 로드되고 완전히 초기화된 후에 명령을 실행하도록 할 수 있습니다. 추가 디버깅 헬퍼를 로드하거나 기존 헬퍼를 수정하려면 환경설정 > Debugger > Locals & Expressions 로 이동하여 Debugging Helper Customization 필드에 명령을 입력합니다.

GDB를 사용할 때 신호 수신에 대한 오류 메시지가 표시되는 경우 신호 처리를 위한 GDB 명령을 지정할 수 있습니다. 예를 들어 다음과 같은 오류 메시지가 표시되는 경우 SIGSTOP 신호를 무시하도록 GDB에 지시할 수 있습니다: The debugged process stopped because it received a signal from the operating system. Signal name: SIGSTOP.
GDB가 SIGSTOP 신호를 처리하지 않도록 하려면 Debugging Helper Customization 필드에 다음 명령을 추가하세요:
handle SIGSTOP nopass handle SIGSTOP nostop
디버깅 중에 애플리케이션이 신호를 수신하는 즉시 메시지 상자를 표시하려면 환경설정 > Debugger > GDB > Show a message box when receiving a signal 로 이동합니다.
사용자 지정 디버깅 헬퍼 추가하기
자체 유형에 대한 디버깅 헬퍼를 추가하려면 컴파일할 필요 없이 파이썬 몇 줄만 추가하면 됩니다. 스크립트는 여러 버전의 Qt 또는 자체 라이브러리를 동시에 처리할 수 있습니다.
사용자 정의 유형에 대한 디버깅 헬퍼를 추가하려면 디버거의 시작 파일(예: ~/.gdbinit 또는 ~/.lldbinit)에 디버깅 헬퍼 구현을 추가하거나 환경설정 > Debugger > GDB 의 Additional Startup Commands 에서 직접 지정합니다.
자체 데이터 유형에 대한 디버깅 헬퍼 구현을 시작하려면 Qt 설치 또는 독립형 Qt Creator 설치의 share/qtcreator/debugger/personaltypes.py 파일에 해당 구현을 넣으면 됩니다. macOS의 경우 이 파일은 Qt Creator 애플리케이션 패키지에 번들로 제공되며, Contents/resources/debugger 폴더에 있습니다.
personaltypes.py 파일에는 구현 예제가 하나 있습니다:
# def qdump__MapNode(d, value):
# d.putValue("This is the value column contents")
# d.putExpandable()
# if d.isExpanded():
# with Children(d):
# # Compact simple case.
# d.putSubItem("key", value["key"])
# # Same effect, with more customization possibilities.
# with SubItem(d, "data")
# d.putItem("data", value["data"])디버깅 헬퍼를 추가하려면 다음과 같이 하세요:
share/qtcreator/debugger/personaltypes.py파일을 열어 편집합니다. 예를 들어, Qt 설치 디렉터리가 Windows의Qt5디렉터리에 있는 경우C:\Qt5\Tools\QtCreator\share\qtcreator\debugger을 찾습니다. macOS에서는Qt5/Qt Creator.app/Contents/resources/debugger.personaltypes.py파일 끝에 덤퍼 구현을 추가합니다. 디버깅 헬퍼 구현에 대한 자세한 내용은 다음 섹션을 참조하세요.- Qt Creator 설치를 업데이트할 때(예를 들어 Qt 설치를 업데이트할 때)
personaltypes.py을 덮어쓰는 것을 방지하려면 파일 시스템에서 Qt Creator 설치 외부의 안전한 위치에 복사하고 Preferences > Debugger > Locals & Expressions > Extra Debugging Helper 에서 위치를 지정합니다.
Qt Creator 에서 디버깅 세션을 시작하거나 디버거 로그 보기의 컨텍스트 메뉴에서 Reload Debugging Helpers 을 선택하면 사용자 정의 디버깅 헬퍼가 personaltypes.py 에서 자동으로 선택됩니다.
디버깅 헬퍼 개요
디버깅 헬퍼의 구현은 일반적으로 단일 Python 함수로 구성되며, 이름은 qdump__NS__Foo, 여기서 NS::Foo 은 검사할 클래스 또는 클래스 템플릿입니다. :: 범위 확인 연산자는 이중 밑줄로 대체됩니다( __). 중첩된 네임스페이스가 가능합니다. 템플릿 인수는 함수 이름 구성에 사용되지 않습니다.
예시:
namespace Project { template<typename T> struct Foo {... } }유형에 대한 디버깅 헬퍼를 구현하는 함수의 이름은qdump__Project__Foo입니다.std::__1::vector<T>::iterator유형에 대한 디버깅 헬퍼를 구현하는 함수의 이름은qdump__std____1__vector__iterator입니다.
Qt Creator의 디버거 플러그인은 이 유형의 객체를 표시할 때마다 이 함수를 호출합니다. 이 함수에는 다음 매개변수가 전달됩니다:
d현재 설정이 있고 Locals 및 Expressions 보기의 일부를 나타내는 객체를 작성하는 기능을 제공하는Dumper유형의 객체.valuegdb.Value 또는 lldb.SBValue를 래핑하는Value유형입니다.
qdump__* 함수는 Locals 및 Expressions 보기에서 객체와 그 하위 표시를 구축하는 데 사용되는 특정 정보를 덤퍼 객체에 공급해야 합니다.
예시:
def qdump__QFiniteStack(d, value): alloc = value["_alloc"].integer() size = value["_size"].integer() d.putItemCount(size) if d.isExpanded(): d.putArrayData(value["_array"], size, value.type[0])
참고: LLDB 및 GDB 백엔드 모두에서 사용할 수 있는 덤퍼 함수를 만들려면 gdb.* 및 lldb.* 네임스페이스에 직접 액세스하지 말고 대신 Dumper 클래스의 함수를 사용하세요.
디버깅 헬퍼에서 객체의 기본 인스턴스로 이동하려면 value.base() 함수 또는 다음 예제 코드를 사용하세요:
def qdump__A(d, value): t = value.members(True)[0].type dptr, base_v = value.split('p{%s}' % t.name) d.putItem(base_v)
유형 이름이 정규식과 일치할 때마다 디버깅 헬퍼가 호출되도록 설정할 수 있습니다. 이렇게 하려면 디버깅 헬퍼의 함수 이름이 qdump__ (밑줄 두 개 포함)로 시작해야 합니다. 또한 함수에는 유형 이름이 일치해야 하는 정규식을 지정하는 기본값을 가진 regex 이라는 세 번째 매개 변수가 있어야 합니다.
예를 들어, Nim 0.12 컴파일러는 컴파일하는 모든 일반 시퀀스에 TY1 및 TY2 과 같은 인위적인 이름을 할당합니다. 이를 Qt Creator 에서 시각화하려면 다음 디버깅 헬퍼를 사용할 수 있습니다:
def qdump__NimGenericSequence__(d, value, regex = "^TY.*$"): size = value["Sup"]["len"] base = value["data"].dereference() typeobj = base.dereference().type d.putArrayData(base, size, typeobj)
디버깅 헬퍼 구현
디버깅 헬퍼는 표시된 데이터 항목에 대한 설명을 GDB/MI 및 JSON과 유사한 형식으로 작성합니다.
Locals 및 Expressions 보기의 각 줄에 대해 다음과 같은 문자열을 만들어 디버거 플러그인으로 채널링해야 합니다.
{ iname='some internal name', # optional
address='object address in memory', # optional
name='contents of the name column', # optional
value='contents of the value column',
type='contents of the type column',
numchild='number of children', # zero/nonzero is sufficient
children=[ # only needed if item is expanded in view
{iname='internal name of first child',
},
{iname='internal name of second child',
},
]}iname 필드의 값은 개체의 내부 이름으로, 점으로 구분된 식별자 목록으로 구성되며 뷰에서 개체가 표시되는 위치에 해당합니다. 이 이름이 없는 경우 상위 개체의 iname, 점 및 일련 번호를 연결하여 생성됩니다.
name 필드의 값은 뷰의 Name 열에 표시됩니다. 지정하지 않으면 괄호 안의 간단한 숫자가 대신 사용됩니다.
이 형식은 안정성이 보장되지 않으므로 와이어 형식을 직접 생성하지 말고 Python 덤퍼 클래스의 추상화 계층, 특히 Dumper 클래스 자체와 Dumper:Value 및 Dumper:Type 추상화를 사용하는 것이 좋습니다. 이들은 iname 및 addr 필드를 처리하고, 간단한 유형, 참조, 포인터, 열거형, 알려진 구조체 및 알 수 없는 구조체의 자식을 처리하는 완전한 프레임워크와 일반적인 상황을 처리하는 몇 가지 편의 기능을 제공합니다.
CDB를 디버거 백엔드로 사용하는 경우 환경설정 > Debugger > CDB > Use Python dumper 을 선택하여 Python 덤퍼를 활성화할 수 있습니다.

다음 섹션에서는 qtcreator\share\qtcreator\debugger\dumper.py 에 지정된 널리 사용되는 덤퍼 클래스와 멤버 중 일부를 설명합니다.
덤퍼 클래스
Dumper 클래스에는 일반적인 부기, 저수준 및 편의 기능이 있습니다:
putItem(self, value)- 기본 유형, 참조, 포인터 및 열거형을 직접 처리하고, 기본 클래스와 복합 유형의 클래스 멤버를 반복하며, 적절한 경우qdump__*함수를 호출하는 마스터 함수입니다.putIntItem(self, name, value)- 에 해당합니다:with SubItem(self, name): self.putValue(value) self.putType("int")
putBoolItem(self, name, value)- 동등한: 다음과 같습니다:with SubItem(self, name): self.putValue(value) self.putType("bool")
putCallItem(self, name, rettype, value, func, *args)- 디버거 백엔드를 사용하여 value 에 지정된 값에rettype을 반환하는func함수를 호출하고 결과 항목을 출력합니다.네이티브 호출은 매우 강력하며 예를 들어 디버깅 프로세스에서 기존 디버깅 또는 로깅 기능을 활용할 수 있습니다. 하지만 다음과 같은 이유로 데이터에 액세스할 다른 방법이 없는 경우에만 통제된 환경에서만 사용해야 합니다:
- 코드를 직접 실행하는 것은 위험합니다. 디버깅된 프로세스의 권한으로 네이티브 코드를 실행하므로 디버깅된 프로세스를 손상시킬 뿐만 아니라 디스크 및 네트워크에 액세스할 수 있습니다.
- 핵심 파일을 검사할 때는 호출을 실행할 수 없습니다.
- 호출은 디버거에서 설정하고 실행하는 데 많은 비용이 듭니다.
putArrayData(self, address, itemCount, type)-address에 있는 배열형 객체의type유형으로itemCount에 지정된 자식 수를 생성합니다.putSubItem(self, component, value)- 에 해당합니다:with SubItem(self, component): self.putItem(value)
중첩된 함수 호출로 인해 발생한 예외가 포착되고
putItem에서 생성된 모든 출력이 의 출력으로 대체됩니다:except RuntimeError: d.put('value="<invalid>",type="<unknown>",numchild="0",')put(self, value)- 출력 문자열에 직접 추가하는 저수준 함수입니다. 이는 출력을 추가하는 가장 빠른 방법이기도 합니다.putField(self, name, value)-name='value'필드를 추가합니다.childRange(self)- 현재Children범위에 지정된 자식 범위를 반환합니다.putItemCount(self, count)-value='<%d items>'필드를 출력에 추가합니다.putName(self, name)-name=''필드를 추가합니다.putType(self, type, priority=0)- type 이 부모의 기본 하위 유형과 일치하거나putType이 더 높은 값인priority으로 현재 항목에 대해 이미 호출된 경우를 제외하고type=''필드를 추가합니다.putBetterType(self, type)- 마지막으로 기록된type을 재정의합니다.putExpandable(self)- 현재 값에 대한 하위 항목의 존재를 알립니다. 기본값은 자식 없음입니다.putNumChild(self, numchild)- 현재 값에 대한 하위 항목의 존재(numchild> 0) 또는 존재하지 않음을 알립니다.putValue(self, value, encoding = None)-value=''파일과 선택적으로valueencoding=''필드를 추가합니다.value은 영숫자 값으로만 구성된 문자열로 변환할 수 있어야 합니다. 영숫자 전용 요구 사항을 충족하기 위해 실제 값을 어떤 식으로든 인코딩해야 하는 경우encoding매개 변수를 사용하여 인코딩을 지정할 수 있습니다.encoding매개변수는codec:itemsize:quote형식의 문자열이며codec는latin1,utf8,utf16,ucs4,int,float중 하나입니다.itemsize는codec에 암시되지 않은 경우 객체의 기본 구성 요소의 크기를 제공하며quote는 값을 표시할 때 따옴표로 묶을지 여부를 지정합니다.예시:
# Safe transport of quirky data. Put quotes around the result. d.putValue(d.hexencode("ABC\"DEF"), "utf8:1:1")
putStringValue(self, value)- QString 을 인코딩하고 올바른encoding설정으로putValue을 호출합니다.putByteArrayValue(self, value)- QByteArray 을 인코딩하고 올바른encoding설정으로putValue을 호출합니다.isExpanded(self)- 뷰에서 현재 항목이 확장되었는지 여부를 확인합니다.createType(self, pattern, size = None)-Dumper.Type개체를 만듭니다. 정확한 작업은pattern에 따라 다릅니다.pattern이 잘 알려진 유형의 이름과 일치하는 경우 이 유형을 설명하는Dumper.Type개체가 반환됩니다.pattern이 네이티브 백엔드에 알려진 유형의 이름인 경우 반환된 유형은 네이티브 유형을 설명합니다.- 그렇지 않으면
pattern은 다음과 같이 구조체의 필드를 설명하는 일련의 항목을 해석하여 유형 설명을 구성하는 데 사용됩니다. 필드 설명은 다음과 같이 하나 이상의 문자로 구성됩니다:q- 부호 있는 8바이트 정수 값Q- 부호 없는 8바이트 정수 값i- 부호 있는 4바이트 정수 값I- 부호 없는 4바이트 정수 값h- 부호화된 2바이트 정수 값H- 부호 없는 2바이트 정수 값b- 부호화된 1바이트 정수 값B- 부호 없는 1바이트 적분값d- 8바이트 IEEE 754 부동 소수점 값f- 4바이트 IEEE 754 부동 소수점 값p- 포인터, 즉 대상 아키텍처에 따라 적절한 크기의 부호 없는 정수 값입니다.@- 적절한 패딩. 크기는 앞뒤 필드와 대상 아키텍처에 따라 결정됩니다.<n>s- 암시적 정렬이 1인 <n> 바이트의 블롭입니다.<typename>- 이름이Dumper.Type인 적절한 크기와 적절한 정렬의 블롭입니다.typename
Dumper.Type 클래스
Dumper.Type 클래스는 데이터의 유형(일반적으로 C++ 클래스나 구조체, 구조체에 대한 포인터, 정수형이나 부동 소수점형과 같은 기본 유형)을 설명합니다.
유형 객체, 즉 Dumper.Type 클래스의 인스턴스는 디버거 백엔드에서 일반적으로 디버깅된 바이너리에 내장되거나 함께 제공되는 디버그 정보를 평가하여 만들거나 디버깅 헬퍼를 통해 즉석에서 만들 수 있습니다.
Qt Creator 는 대부분의 Qt 클래스에 대해 즉시 유형 정보를 제공하므로, 객체 내성 검사 목적으로 Qt의 디버그 빌드를 사용할 필요가 없어집니다.
Dumper.Type 클래스에는 다음과 같이 널리 사용되는 멤버 함수가 있습니다:
name- 이 타입의 이름을 문자열로 반환하거나, 타입이 익명인 경우None.size(self)- 이 타입의 객체의 크기를 바이트 단위로 반환합니다.bitsize(self)- 이 유형의 객체의 크기를 비트로 반환합니다.alignment(self)- 이 유형의 객체에 필요한 정렬을 바이트 단위로 반환합니다.deference(self)- 포인터 타입의 경우 역참조 타입을 반환하고, 그렇지 않으면None을 반환합니다.pointer(self)- 이 타입으로 역참조할 수 있는 포인터 타입을 반환합니다.target(self)- 배열 타입의 경우 항목 타입을, 포인터와 참조의 경우 역참조된 타입을 반환하는 편의 함수입니다.stripTypedefs(self)- 이 유형이 별칭인 경우 기본 유형을 반환합니다.templateArgument(self, position, numeric = False)- 템플릿 유형인 경우position에 있는 템플릿 매개변수를 반환합니다.numeric이True인 경우 매개변수를 정수 값으로 반환합니다.fields(self)- 이 유형의 기본 클래스와 데이터 멤버를 설명하는Dumper:Fields목록을 반환합니다.
Dumper.Field 클래스
Dumper.Field 클래스는 타입 객체의 베이스 클래스 또는 데이터 멤버를 설명합니다:
isBaseClass- 베이스 클래스와 데이터 멤버를 구분합니다.fieldType(self)- 이 기본 클래스 또는 데이터 멤버의 형을 반환합니다.parentType(self)- 소유 유형을 반환합니다.bitsize(self)- 이 필드의 크기를 비트 단위로 반환합니다.bitpos(self)- 소유 유형에서 이 필드의 오프셋을 비트 단위로 반환합니다.
Dumper.Value 클래스
Dumper.Value 클래스는 C++ 클래스의 인스턴스나 원시 데이터 유형과 같은 데이터를 설명합니다. 또한 파일 내용, 비연속 객체 또는 컬렉션과 같이 메모리에 직접 표현되지 않는 인위적인 항목을 설명하는 데 사용할 수도 있습니다.
Dumper.Value 에는 항상 Dumper.Type 이 연관되어 있습니다. 값의 실제 데이터에 대한 두 가지 주요 표현은 다음과 같습니다:
- 파이썬 버퍼 프로토콜을 따르는 파이썬 객체(예: 파이썬
memoryview, 또는bytes객체).size()은 이 값의 유형 크기와 일치해야 합니다. - 현재 주소 공간에서 객체의 시작 부분에 대한 포인터를 나타내는 정수 값입니다. 객체의 크기는 해당 유형의
size()에 의해 제공됩니다.
Dumper.Value 의 내부 표현에 대한 지식은 일반적으로 디버거 헬퍼를 만들 때 필요하지 않습니다.
Dumper.Value 클래스의 멤버 함수와 프로퍼티는 다음과 같습니다:
integer(self)- 이 값의 해석을 적절한 크기의 부호화된 적분 값으로 반환합니다.pointer(self)- 이 값의 해석을 현재 주소 공간의 포인터로 반환합니다.members(self, includeBases)- 이 값의 기본 객체와 데이터 멤버를 나타내는Dumper.Value객체 목록을 반환합니다.dereference(self)- 포인터를 설명하는 값의 경우 역참조된 값을 반환하고, 그렇지 않으면None을 반환합니다.cast(self, type)- 이 값과 데이터는 같지만 유형이type인 값을 반환합니다.address(self)- 이 값의 주소가 현재 주소 공간에서 인접한 영역으로 구성된 경우 이 값의 주소를 반환하고, 그렇지 않으면None을 반환합니다.data(self)- 이 값의 데이터를 Pythonbytes객체로 반환합니다.split(self, pattern)- 이 값의 데이터에서pattern에 따라 생성된 값의 목록을 반환합니다. 허용되는 패턴은Dumper.createType와 동일합니다.dynamicTypeName(self)- 이 값이 베이스 클래스 객체인 경우 이 값의 동적 유형 이름을 검색하려고 시도합니다. 가능하지 않은 경우None을 반환합니다.
하위 항목 및 하위 항목 클래스
데이터가 초기화되지 않았거나 손상된 경우 하위 항목을 만들려고 하면 오류가 발생할 수 있습니다. 이러한 상황에서 정상적으로 복구하려면 Children 및 SubItem 컨텍스트 관리자를 사용하여 중첩된 항목을 만드세요.
Children 생성자 __init__(self, dumper, numChild = 1, childType = None, childNumChild = None, maxNumChild = None, addrBase = None, addrStep = None) 는 하나의 필수 인수와 여러 개의 선택적 인수를 사용합니다. 필수 인수는 현재 Dumper 객체를 참조합니다. 선택적 인수는 각각 childType_ 및 childNumChild_ 손자손녀 유형으로 numChild 자식 수를 지정하는 데 사용할 수 있습니다. maxNumChild 을 지정하면 해당 수의 자식만 표시됩니다. 그렇지 않으면 지나치게 오래 걸릴 수 있는 컨테이너 콘텐츠를 덤프할 때 이 옵션을 사용해야 합니다. addrBase 및 addrStep 매개 변수를 사용하면 하위 덤퍼에서 생성되는 데이터의 양을 줄일 수 있습니다. n번째자식 항목의 주소가 addrBase + n * addrStep과 같으면 주소 인쇄가 억제됩니다.
예시:
if d.isExpanded(): with Children(d): with SubItem(d): d.putName("key") d.putItem(key) with SubItem(d): d.putName("value") d.putItem(value)
다음과 같이 더 편리하게 작성할 수 있습니다:
d.putNumChild(2) if d.isExpanded(): with Children(d): d.putSubItem("key", key) d.putSubItem("value", value)
Copyright © The Qt Company Ltd. and other contributors. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.