Pomoćnici za otklanjanje pogrešaka
Qt Creator koristi Python skripte za prevođenje sirovog sadržaja memorije i podataka o informacijama o tipu iz backenda za otklanjanje pogrešaka (trenutno podržani GDB, LLDB i CDB) u oblik prikazan korisniku u prikazima Lokalne varijable i Izrazi.
Za razliku od GDB-ovih pretty printera i LLDB-ovih formatera podataka, pomoćnici za otklanjanje pogrešaka u Qt Creator u ne ovise o izvornom backendu za otklanjanje pogrešaka. To jest, isti se kod može koristiti s GDB-om na Linuxu, LLDB-om na macOS-u i CDB-om na Windowsima, ili na bilo kojoj drugoj platformi na kojoj je dostupna barem jedna od tri podržane pozadinske usluge.
Da biste koristili zadane GDB-ove 'pretty printere' instalirane na vašem sustavu ili povezane s bibliotekama koje vaša aplikacija koristi, idite na Preferences > Debugger > GDB > Load system GDB pretty printers. Za više informacija pogledajte GDB.

Prilagodba ugrađenih pomoćnika za otklanjanje pogrešaka
Možete izvršiti naredbe nakon što su ugrađeni pomoćnici za otklanjanje pogrešaka učitani i u potpunosti inicijalizirani. Da biste učitali dodatne pomoćnike za otklanjanje pogrešaka ili izmijenili postojeće, idite na Preferences > Debugger > Locals & Expressions i unesite naredbe u polje Debugging Helper Customization.

Ako primate poruke o pogreškama o primanju signala pri korištenju GDB-a, možete odrediti GDB naredbe za obradu tih signala. Na primjer, možete reći GDB-u da zanemari signal SIGSTOP ako primite sljedeću poruku o pogrešci: The debugged process stopped because it received a signal from the operating system. Signal name: SIGSTOP.
Da biste zaustavili GDB u obradi signala SIGSTOP, dodajte sljedeće naredbe u polje Debugging Helper Customization:
handle SIGSTOP nopass handle SIGSTOP nostop
Da biste prikazali okvir za poruke čim vaša aplikacija primi signal tijekom otklanjanja pogrešaka, idite na Preferences > Debugger > GDB > Show a message box when receiving a signal.
Dodavanje prilagođenih pomoćnika za otklanjanje pogrešaka
Za dodavanje debug pomoćnika za vlastite tipove nije potrebna kompilacija, već samo dodavanje nekoliko redaka Pythona. Skripte mogu istovremeno obrađivati više verzija Qt-a ili vaše vlastite biblioteke.
Da biste dodali pomoćnike za otklanjanje pogrešaka za prilagođene tipove, dodajte implementacije pomoćnika za otklanjanje pogrešaka u početnu datoteku otklanjača pogrešaka (na primjer, ~/.gdbinit ili ~/.lldbinit) ili ih navedite izravno u Additional Startup Commands u Preferences > Debugger > GDB.
Za početak implementacije pomoćnika za otklanjanje pogrešaka za vlastite tipove podataka, njihovu implementaciju možete smjestiti u datoteku share/qtcreator/debugger/personaltypes.py u vašoj Qt instalaciji ili u samostalnoj instalaciji Qt Creator. Na macOS-u je datoteka uključena u paket aplikacije Qt Creator, gdje se nalazi u mapi Contents/resources/debugger.
Datoteka personaltypes.py sadrži jedan primjer implementacije:
# 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"])Za dodavanje pomoćnih alata za otklanjanje pogrešaka:
- Otvorite datoteku
share/qtcreator/debugger/personaltypes.pyza uređivanje. Na primjer, na Windowsima pogledajte uC:\Qt\Tools\QtCreator\share\qtcreator\debugger. Na macOS-u pogledajte uQt Creator.app/Contents/resources/debugger. - Dodajte svoju implementaciju dumpéra na kraj datoteke
personaltypes.py. Za više informacija o implementaciji pomoćnika za otklanjanje pogrešaka pogledajte sljedeće odjeljke. - Kako biste spriječili prebrisavanje datoteke
personaltypes.pyprilikom ažuriranja instalacije Qt Creator (na primjer, prilikom ažuriranja instalacije Qt-a), kopirajte je na sigurno mjesto izvan instalacije Qt Creator na vašem sustavu datoteka i navedite tu lokaciju u Preferences > Debugger > Locals & Expressions > Extra Debugging Helper.
Prilagođeni pomoćnici za otklanjanje pogrešaka automatski će se učitati iz personaltypes.py kada pokrenete sesiju otklanjanja pogrešaka u Qt Creator ili odaberete Reload Debugging Helpers iz kontekstnog izbornika prikaza dnevnika otklanjanja pogrešaka.
Pregled pomoćnika za otklanjanje pogrešaka
Implementacija pomoćnika za otklanjanje pogrešaka obično se sastoji od jedne Python funkcije koja mora biti nazvana qdump__NS__Foo, gdje je NS::Foo klasa ili predložak klase koji se ispituje. Imajte na umu da se operator za rješavanje opsega :: zamjenjuje dvostrukim podcrtavima: __. Mogući su ugniježđeni imenski prostori. Argumenti predloška se ne koriste za izgradnju naziva funkcije.
Primjeri:
- Naziv funkcije koja implementira pomoćnik za otklanjanje pogrešaka za tip
namespace Project { template<typename T> struct Foo {... } }jeqdump__Project__Foo. - Naziv funkcije koja implementira pomoćnik za otklanjanje pogrešaka za tip
std::__1::vector<T>::iteratorjeqdump__std____1__vector__iterator.
Qt Creator's debugger dodatak poziva ovu funkciju kad god želite prikazati objekt ove vrste. Funkciji se prosljeđuju sljedeći parametri:
dod tipaDumper, objekt koji ima trenutne postavke i pruža mogućnosti za izgradnju objekta koji predstavlja dio prikaza Locals i Expressions.valuetipaValue, koji obavija ili gdb.Value ili lldb.SBValue.
Funkcija qdump__* mora napojiti objekt Dumper određenim informacijama koje se koriste za izgradnju prikaza objekta i njegovih podređenih elemenata u prikazima Locals i Expressions.
Primjer:
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])
Napomena: Kako biste stvorili dumper funkcije koje se mogu koristiti s oba LLDB i GDB backenda, izbjegavajte izravan pristup imenskim prostorima gdb.* i lldb.* te umjesto toga koristite metode klase Dumper.
Da biste došli do osnovne instance objekta u pomoćniku za otklanjanje pogrešaka, upotrijebite funkciju value.base() ili sljedeći primjer koda:
def qdump__A(d, value): t = value.members(True)[0].type dptr, base_v = value.split('p{%s}' % t.name) d.putItem(base_v)
Pomoćne funkcije za otklanjanje pogrešaka mogu se postaviti da se pozivaju kad god naziv tipa odgovara regularnom izrazu. Da biste to učinili, naziv funkcije pomoćne funkcije za otklanjanje pogrešaka mora započeti s qdump__ (s dva znaka podcrtavanja). Osim toga, funkcija mora imati treći parametar nazvan regex s zadanoj vrijednošću koja određuje regularni izraz kojem naziv tipa treba odgovarati.
Na primjer, kompajler Nim 0.12 dodjeljuje umjetna imena, kao što su TY1 i TY2, svim generičkim sekvencama koje kompajlira. Za njihovu vizualizaciju u Qt Creator može se koristiti sljedeći pomoćnik za otklanjanje pogrešaka:
def qdump__NimGenericSequence__(d, value, regex = "^TY.*$"): size = value["Sup"]["len"] base = value["data"].dereference() typeobj = base.dereference().type d.putArrayData(base, size, typeobj)
Implementacija pomoćnika za otklanjanje pogrešaka
Pomoćnik za otklanjanje pogrešaka stvara opis prikazanog stavka podataka u formatu sličnom GDB/MI i JSON-u.
Za svaki redak u prikazima Locals i Expressions potrebno je stvoriti niz poput sljedećeg i proslijediti ga dodatku za otklanjanje pogrešaka.
{ 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',
},
]}Vrijednost polja iname je interno ime objekta, koje se sastoji od popisa identifikatora odvojenih točkom, a koje odgovara položaju prikaza objekta u pogledu. Ako ono ne postoji, generira se spajanjem iname-a roditeljskog objekta, točke i slijednog broja.
Vrijednost polja name prikazuje se u stupcu Name pogleda. Ako nije navedena, umjesto toga se koristi jednostavan broj u zagradama.
Budući da format nije zajamčeno stabilan, snažno se preporučuje ne generirati format žice izravno, već koristiti sloj apstrakcije klasa Python Dumper, posebice samu klasu Dumper i apstrakcije Dumper:Value i Dumper:Type. Oni nude potpuni okvir za rukovanje poljima iname i addr, za obradu djece jednostavnih tipova, referenci, pokazivača, enuma te poznatih i nepoznatih struktura, kao i neke praktične funkcije za rješavanje uobičajenih situacija.
Kada koristite CDB kao pozadinski debuger, možete omogućiti Python dumper odabirom Preferences > Debugger > CDB > Use Python dumper.

Sljedeći odjeljci opisuju neke od široko korištenih klasa i članova Dumpera navedenih u qtcreator\share\qtcreator\debugger\dumper.py.
Klasa Dumper
Klasa Dumper ima generičke, nisko-razinske i pomoćne funkcije:
putItem(self, value)- Glavna funkcija koja izravno obrađuje osnovne tipove, reference, pokazivače i enumove, prolazi kroz temeljne klase i članove složenih tipova te po potrebi poziva funkcijeqdump__*.putIntItem(self, name, value)- Ekvivalentno:with SubItem(self, name): self.putValue(value) self.putType("int")
putBoolItem(self, name, value)- Ekvivalentno:with SubItem(self, name): self.putValue(value) self.putType("bool")
putCallItem(self, name, rettype, value, func, *args)- Koristi backend otklanjanja pogrešaka za postavljanje poziva funkcijefunckoja vraćarettypena vrijednost navedenu pomoću value i za izlazak dobivenog stavka.Nativni pozivi su izuzetno moćni i, na primjer, mogu iskoristiti postojeće alate za otklanjanje pogrešaka ili logiranje u procesu koji se otklanja. Međutim, trebali bi se koristiti samo u kontroliranom okruženju i samo ako ne postoji drugi način za pristup podacima, iz sljedećih razloga:
- Izravna izvedba koda je opasna. Izvršava nativni kod s privilegijama procesa pod istragom, što može dovesti ne samo do oštećenja tog procesa, već i do pristupa disku i mreži.
- Pozivi se ne mogu izvršiti pri pregledavanju core datoteke.
- Pozivi su skupi za postavljanje i izvršavanje u otklanjivaču pogrešaka.
putArrayData(self, address, itemCount, type)- Stvara broj podređenih procesa navedenih pomoćuitemCount, tipatype, iz objekta nalik nizu smještenog na adresiaddress.putSubItem(self, component, value)- Ekvivalentno:with SubItem(self, component): self.putItem(value)
Izuzeci podignuti pozivima funkcija ugniježđenih u catch-klausuli se uhvate i sav izlaz proizveden pozivom
putItemzamjenjuje se izlazom od:except RuntimeError: d.put('value="<invalid>",type="<unknown>",numchild="0",')put(self, value)- Funkcija niske razine za izravno dodavanje u izlaznu niz. To je također najbrži način dodavanja izlaza.putField(self, name, value)- Dodaje poljename='value'.childRange(self)- Vraća raspon djece navedenih u trenutnom opseguChildren.putItemCount(self, count)- Dodaje poljevalue='<%d items>'u izlaz.putName(self, name)- Dodaje poljename=''.putType(self, type, priority=0)- Dodaje poljetype='', osim ako se type ne podudara s podrazumijevanim tipom djeteta roditelja ili jeputTypeveć pozvan za trenutni element s višom vrijednošćupriority.putBetterType(self, type)- Prepisuje posljednje zabilježenotype.putExpandable(self)- Obavještava o postojanju podređenih stavki za trenutnu vrijednost. Po zadanom nema podređenih stavki.putNumChild(self, numchild)- Objavljuje postojanje (numchild> 0) ili nepostojanje podređenih stavki za trenutnu vrijednost.putValue(self, value, encoding = None)- Dodaje datotekuvalue='', po želji praćenu poljemvalueencoding=''.valuemora biti konvertibilan u niz koji se u potpunosti sastoji od alfanumeričkih vrijednosti. Parametarencodingmože se koristiti za navođenje kodiranja u slučaju da je stvarna vrijednost morala biti nekako kodirana kako bi se zadovoljio zahtjev da sadrži samo alfanumeričke znakove. Parametarencodingje niz oblikacodec:itemsize:quote, gdjecodecmože biti bilo koji od sljedećih:latin1,utf8,utf16,ucs4,intilifloat.itemsizeodređuje veličinu osnovne komponente objekta ako to nije implicitno definirano parametromcodec, aquoteodređuje treba li vrijednost biti okružena navodnicima pri prikazu.Primjer:
# Safe transport of quirky data. Put quotes around the result. d.putValue(d.hexencode("ABC\"DEF"), "utf8:1:1")
putStringValue(self, value)- Kodira QString i pozivaputValues ispravnom postavkomencoding.putByteArrayValue(self, value)- Kodira QByteArray i pozivaputValues ispravnom postavkomencoding.isExpanded(self)- Provjerava je li trenutni element proširen u prikazu.createType(self, pattern, size = None)- Stvara objektDumper.Type. Točna operacija ovisi opattern.- Ako
patternodgovara nazivu dobro poznate vrste, vraća se objektDumper.Typekoji opisuje tu vrstu. - Ako je
patternime tipa poznatog nativnom backendu, vraćeni tip opisuje nativni tip. - U suprotnom se
patternkoristi za izgradnju opisa tipa interpretiranjem niza stavki koje opisuju polje strukture na sljedeći način. Opisi polja sastoje se od jednog ili više znakova na sljedeći način:q- Potpisani 8-bajtni cjelobrojni brojQ- Bezpredznak vrijednost cjelobrojne vrijednosti od 8 bajtovai- Potpisana 4-bajtna cjelobrojna vrijednostI- Nesignirana 4-bajtna cjelobrojna vrijednosth- Potpisana 2-bajtna cjelobrojna vrijednostH- Neznakovani 2-bajtni cjelobrojni brojb- Potpisana 1-bajtna cjelobrojna vrijednostB- Bezpredznakova 1-bajtna cjelobrojna vrijednostd- 8-bajtna IEEE 754 vrijednost s pomičnom zarezomf- 4-bajtna IEEE 754 vrijednost s pomičnom zarezomp- Pokazatelj, tj. bezpredznakova cjelobrojna vrijednost odgovarajuće veličine prema ciljnoj arhitekturi@- Primjereno popunjavanje. Veličina se određuje prethodnim i sljedećim poljem te ciljanom arhitekturom<n>s- Blob od <n> bajtova, s implicitnim poravnanjem od 1<typename>- Blob odgovarajuće veličine i odgovarajućeg poravnanja određen pomoćuDumper.Typea s imenomtypename
- Ako
Klasa Dumper.Type
Klasa Dumper.Type opisuje tip dijela podataka, obično C++ klasu ili strukturu, pokazivač na strukturu ili primitivni tip, kao što je cjelobrojni ili pomični tip.
Objekti tipa, odnosno instanci klase Dumper.Type, mogu se stvoriti pomoću back-endova otklonika, obično evaluacijom informacija za otklanjanje pogrešaka ugrađenih u ili priloženih uz binarnu datoteku koja se otklanja, ili se mogu stvoriti u letu pomoću pomoćnika za otklanjanje pogrešaka.
Qt Creator nudi informacije o tipu u hodu za većinu Qt klasa, čime se ukida potreba za korištenjem debug verzija Qt-a u svrhu introspekcije objekata.
Klasa Dumper.Type ima sljedeće široko korištene članice:
name- Naziv ove vrste kao niz znakova, iliNoneako je vrsta anonimna.size(self)- Vraća veličinu objekta ove vrste u bajtima.bitsize(self)- Vraća veličinu objekta ove vrste u bitovima.alignment(self)- Vraća potrebnu poravnatost za objekte ove vrste u bajtima.deference(self)- Vraća tip za dereferenciranje pokazivača, inačeNone.pointer(self)- Vraća tip pokazivača koji se može de-referencirati na ovaj tip.target(self)- Pomoćna funkcija koja vraća tip stavke za tipove nizova i tip nakon dereferenciranja za pokazivače i reference.stripTypedefs(self)- Vraća temeljni tip ako je ovaj tip alias.templateArgument(self, position, numeric = False)- Vraća parametar predloška na adresipositionako je ovo tip s predloškom. Ako jenumericTrue, vraća parametar kao cjelobrojnu vrijednost.fields(self)- Vraća popisDumper:Fieldskoji opisuju temeljne klase i članove podataka ove vrste.
Klasa Dumper.Field
Klasa Dumper.Field opisuje osnovnu klasu ili član podataka objekta:
isBaseClass- Razlikuje bazne klase i članove podataka.fieldType(self)- Vraća tip ove osnovne klase ili člana podataka.parentType(self)- Vraća vlasnički tip.bitsize(self)- Vraća veličinu ovog polja u bitima.bitpos(self)- Vraća pomak ovog polja u vlasničkom tipu u bitima.
Klasa Dumper.Value
Klasa Dumper.Value opisuje dio podataka, kao što su instance C++ klasa ili primitivni tipovi podataka. Također se može koristiti za opisivanje umjetnih stavki koje nemaju izravnu reprezentaciju u memoriji, kao što su sadržaj datoteka, neuzastopni objekti ili kolekcije.
Dumper.Value uvijek ima pridruženu Dumper.Type. Dvije glavne reprezentacije stvarnih podataka vrijednosti su:
- Python objekt koji slijedi Python protokol za buffer, kao što je Python
memoryviewilibytesobjekt.size()mora odgovarati veličini tipa ove vrijednosti. - Integer vrijednost koja predstavlja pokazivač na početak objekta u trenutnom adresnom prostoru. Veličinu objekta određuje
size()njegovog tipa.
Dumper.Value Poznavanje interne reprezentacije objekta obično nije potrebno pri izradi pomoćnika za otklanjanje pogrešaka za njega.
Član funkcija i svojstva klase Dumper.Value su sljedeći:
integer(self)- Vraća interpretaciju ove vrijednosti kao potpisani integralni broj odgovarajuće veličine.pointer(self)- Vraća interpretaciju ove vrijednosti kao pokazivač u trenutnom adresnom prostoru.members(self, includeBases)- Vraća popis objekata klaseDumper.Valuekoji predstavljaju osnovne objekte i članove podataka ove vrijednosti.dereference(self)- Za vrijednosti koje opisuju pokazivače vraća dereferenciranu vrijednost, a inače vraćaNone.cast(self, type)- Vraća vrijednost koja ima iste podatke kao i ova vrijednost, ali tipatype.address(self)- Vraća adresu ove vrijednosti ako se ona sastoji od uzastopnog područja u trenutnom adresnom prostoru, a inače vraćaNone.data(self)- Vraća podatke ove vrijednosti kao Python objektbytes.split(self, pattern)- Vraća listu vrijednosti stvorenih premapatternod podataka ove vrijednosti. Prihvatljivi obrasci su isti kao i zaDumper.createType.dynamicTypeName(self)- Pokušava dohvatiti naziv dinamičke vrste ove vrijednosti ako je riječ o objektu temeljne klase. VraćaNoneako to nije moguće.
Klasa Children i SubItem
Pokušaj stvaranja podređenih stavki može dovesti do pogrešaka ako su podaci neinkcijalizirani ili oštećeni. Za uredno oporavljanje u takvim situacijama koristite upravljače konteksta Children i SubItem za stvaranje ugniježđenih stavki.
__init__(self, dumper, numChild = 1, childType = None, childNumChild = None, maxNumChild = None, addrBase = None, addrStep = None) Konstruktor klase Children koristi jedan obavezni i nekoliko neobaveznih argumenata. Obavezni argument odnosi se na trenutni objekt Dumper. Neobavezni argumenti mogu se koristiti za navođenje broja djece ( numChild ), pri čemu se za unuke ( childType_ i childNumChild_ ) navodi po jedan tip. Ako je naveden parametar maxNumChild, prikazat će se samo taj broj djece. Ovo se treba koristiti pri ispisivanju sadržaja spremnika koji bi inače mogli potrajati predugo. Parametri addrBase i addrStep mogu se koristiti za smanjenje količine podataka koje proizvode dječji dumpers. Ispis adrese za n-tidječji element bit će suzbijen ako njegova adresa odgovara addrBase + n * addrStep.
Primjer:
if d.isExpanded(): with Children(d): with SubItem(d): d.putName("key") d.putItem(key) with SubItem(d): d.putName("value") d.putItem(value)
Imajte na umu da se ovo može jednostavnije napisati kao:
d.putNumChild(2) if d.isExpanded(): with Children(d): d.putSubItem("key", key) d.putSubItem("value", value)
Vidi također Kako: Debugiranje, Debugiranje i otklanjanje pogrešaka.
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.