Kako koristiti gdbserver za udaljeno otklanjanje pogrešaka na Linuxu

Zadnje ažuriranje: 14/01/2026
Autor: Isaac
  • gdbserver djeluje kao udaljeni agent GDB-a za upravljanje procesima na drugom računalu putem TCP-a ili serijskog porta.
  • Za udaljeno otklanjanje pogrešaka ključno je kompajlirati s simboliKoristite odgovarajući gdb i ispravno konfigurirajte putanje simbola i fontova.
  • gdbserver nudi jednoprocesni i višeprocesni način rada, a također se integrira s WinDbg-om i QEMU-om za otklanjanje pogrešaka u kernelu.
  • Opcije poput --debug, sysroot i ograničenja veličine vrijednosti pomažu u dijagnosticiranju problema i stabilizaciji sesija.

Udaljeno otklanjanje pogrešaka pomoću gdbservera

Ako programirate u C-u ili C++-u Linux i nikad nisi dirao gdbserverPropuštate jedan od najkorisnijih alata za udaljeno otklanjanje pogrešaka u procesima, bilo na poslužitelju, ugrađenom sustavu ili čak unutar virtualnog stroja ili WSL-a. Daleko od toga da je nešto "čarobno" ili rezervirano za stručnjake, gdbserver je jednostavno mali program koji komunicira s gdb-om i kontrolira izvršavanje ciljnog procesa.

Ključna ideja je vrlo jednostavna.: na računalu na kojem se izvršava binarna datoteka koju želite debugirati (the meta) pokrenete gdbserver; na svom radnom računalu ( domaćinPokrećete gdb ili čak WinDbg s podrškom za gdb protokol. Oba se povezuju putem TCP-a ili serijskog porta, a odatle možete postavljati točke prekida, pregledavati varijable, pregledavati stog ili pratiti izvršavanje korak po korak kao da se program izvršava na vašem vlastitom računalu.

Što je gdbserver i kada ga ima smisla koristiti?

Što je gdbserver

gdbserver je udaljeni "agent" za otklanjanje pogrešaka za GNU gdbNjegova funkcija je vrlo specifična: izvršava se na računalu na kojem se izvršava program koji se analizira, kontrolira taj proces (ili procese) i komunicira s gdb klijentom koji se nalazi na drugom računalu (ili na istom) putem udaljene veze.

U svakodnevnoj upotrebi, gdbserver se koristi u dva tipična scenarijaSoftver za otklanjanje pogrešaka koji radi u ugrađenim okruženjima (usmjerivači, ploče s pojednostavljenim Linuxom, uređaji) IOTitd.) i procese otklanjanja pogrešaka na udaljenim Linux računalima, gdje nije zgodno ili jednostavno nije moguće imati "debelu" gdb bazu sa svim bibliotekama i simbolima.

Na praktičnoj razini, gdbserver obavlja zadatke kao što su Čitanje i pisanje registra procesa i memorije, kontrola izvršavanja (nastavak, pauza, prolazak kroz korake), upravljanje točkama prekida i slanje svih ovih podataka gdb-u pomoću GDB udaljenog protokola. Ova filozofija je vrlo slična onoj alata poput OpenOCD-a, koji djeluju kao most između gdb-a i hardver vanjski, s tom razlikom što gdbserver radi na istom sustavu na kojem se pokreće binarna datoteka.

Ako dolazite iz okruženja Windows Također je zanimljivo znati Debuggeri poput WinDbg-a mogu komunicirati s gdbserverom na Linuxu, tako da možete debugirati korisničke procese na Linuxu iz WinDbg-a koristeći podršku za udaljeno debugiranje putem gdb protokola koji je Microsoft uključio u novije verzije.

Osnovni zahtjevi za otklanjanje pogrešaka s gdb-om i gdbserver-om

Zahtjevi za korištenje gdbservera

Prije nego što započnete s udaljenim otklanjanjem pogrešaka, morate razumjeti odnos host/target.. meta To je stroj na kojem se izvršava program koji se debugira i na kojem će se izvršavati gdbserver; domaćin Ovo je stroj s kojeg ćete pokretati gdb (ili WinDbg) i gdje ćete imati izvorni kod i, po mogućnosti, simbole za otklanjanje pogrešaka.

Bitna početna točka je kompajliranje binarne datoteke sa simbolimaU GCC-u ili g++-u to se postiže zastavom -gi obično je preporučljivo onemogućiti optimizacije (na primjer s -O0To omogućuje debuggeru da točnije prikazuje varijable, makroe i strukturu koda. Za određene makroe možete koristiti više razine debugiranja, kao što su -g3.

Na strani hosta trebat će vam kompatibilna verzija gdb-a s ciljnom arhitekturom. Za otklanjanje pogrešaka u MIPS, ARM ili ugrađenom sustavu druge arhitekture, morate koristiti gdb odgovarajućeg cross-toolchaina (na primjer) arm-none-eabi-gdb o gdb-multiarch) i, ako je potrebno, konfigurirati arhitekturu i endianness s naredbe kao set arch y set endian.

Što se tiče veze, gdbserver podržava dva glavna tipaSerijska veza (vrlo česta u ugrađenom hardveru, putem UART-a) i TCP/IP, što je najpraktičnije kada je cilj na istoj mreži ili je Linux stroj dostupan putem mreže. U oba slučaja, naredba se koristi iz gdb-a. target remote za povezivanje s krajnjom točkom koju je otkrio gdbserver.

Načini pokretanja gdbservera: jednoprocesni i višeprocesni način rada

načini izvršavanja gdbservera

gdbserver može raditi na dva glavna načina Kada govorimo o debuggiranju u korisničkom načinu rada: izravno povezano s jednim procesom ili kao "poslužitelj procesa" koji omogućuje popisivanje i povezivanje s različitim sistemskim procesima.

U načinu rada s jednim procesom Pokrećete gdbserver, navodeći host:port i program koji treba pokrenuti. U jednostavnom primjeru na Linux računalu, mogli biste učiniti nešto poput ovoga:

Naredba: gdbserver localhost:3333 foo

S tom naredbom, gdbserver pokreće binarnu datoteku. foo i on ostaje slušati na portu 3333Dok se udaljeni gdb ne poveže, program ostaje zaustavljen; kada se gdb poveže s target remote localhost:3333, proces počinje kontrolirati descrusher.

U višeprocesnom načinu rada (procesni poslužitelj) koristi se opcija --multiU ovom slučaju, gdbserver ne pokreće izravno nijedan program, već jednostavno osluškuje dolazne veze i omogućuje klijentu (gdb ili WinDbg) da upravlja kojim procesom će se kreirati ili kojem će se procesu pripojiti:

  Google lansira Gemini Code Assist: besplatnog pomoćnika za programiranje koji pokreće AI

Naredba: gdbserver --multi localhost:1234

Pri radu s WinDbg-om na Linuxu, ovaj višenamjenski način rada je posebno zanimljiv.Jer iz samog WinDbg-a možete popisati procese na udaljenom sustavu, vidjeti PID, korisnika i komandnu liniju te se pridružiti onome koji vas zanima, slično kao što se to radi s procesnim poslužiteljem. dbgsrv.exe na Windows.

Udaljeno otklanjanje pogrešaka s gdbserverom i gdb korak po korak

Spustimo ovo na zemlju s vrlo tipičnim primjerom.Ispravljanje grešaka u jednostavnoj aplikaciji na istom računalu (podudaranje hosta i cilja) korištenjem gdbserver-a za simulaciju udaljenog scenarija.

Prvo napišete i kompajlirate mali programNa primjer, glupa petlja koja ispisuje brojač:

Naredba: gcc -g foo.c -o foo

Ključna je ovdje zastava -gOvo dodaje potrebne informacije za otklanjanje pogrešaka binarnoj datoteci tako da gdb može prikazati retke koda, nazive varijabli, tipove itd. U "pravom" okruženju cross-compilinga, ovu kompilaciju biste napravili s cross-toolchainom, a zatim kopirali i binarnu datoteku i njezine ovisnosti na cilj.

Sljedeći korak je pokretanje gdbservera na ciljnom serveruAko su host i target isti stroj, tada:

Naredba: gdbserver localhost:3333 foo

Vidjet ćete poruku sličnu „Proces foo created; pid = XXXX; Sluša se port 3333“. To znači da je gdbserver stvorio proces i čeka da se gdb spoji. Ako ste na sustavu gdje su potrebne veće privilegije (na primjer, za povezivanje sa sistemskim procesima), možda ćete morati pokrenuti naredbu s sudoAli uvijek je mudro biti oprezan prilikom davanja dozvole. korijen do desumporizatora.

Na hostu pokrećete gdb navodeći lokalnu izvršnu datoteku (isti onaj koji se izvršava na cilju ili identična kopija sa simbolima):

Naredba: gdb foo

Jednom kada ste unutar gdb-a, uspostavljate udaljenu vezu s:

Naredba: target remote localhost:3333

U tom trenutku, gdb učitava simbole iz lokalne binarne datoteke.Sinkronizira se s gdbserverom i preuzima kontrolu nad procesom koji se zapravo izvršava pod gdbserverom. Odatle je tijek uobičajen: naredbe poput break postaviti prijelomne točke, continue, step, next, print pregledati varijable, backtrace vidjeti bateriju itd.

Povezivanje s pokrenutim procesima pomoću gdbservera

Ne želite uvijek pokrenuti program od nule.Često ste zainteresirani za pridruživanje procesu koji je već u tijeku (na primjer, httpd po usmjerivačsistemski demon ili produkcijska usluga).

Tipičan obrazac je korištenje opcije --attach s gdbserveraprosljeđujući port na kojem će slušati i PID ciljnog procesa. Na primjer, na usmjerivaču na koji ste kopirali gdbserver kompiliran za njegovu arhitekturu, mogli biste učiniti:

Naredba: gdbserver localhost:3333 --attach <pid_de_httpd>

Na strani hosta, koristit ćete verziju gdb-a koja podržava arhitekturu rutera., na primjer gdb-multiarchprethodno konfiguriranje arhitekture i endiannessa:

Naredba: set arch mips
set endian big

Zatim navodite lokalnu datoteku koja sadrži simbole. udaljenog binarnog programa (na primjer file httpd) i, ako je potrebno, gdb-u kažete gdje se binarna datoteka zapravo izvršava na ciljnoj lokaciji s set remote exec-file /usr/bin/httpdKonačno, baš kao i prije, povezujete se sa:

Naredba: target remote 192.168.0.1:3333

Nakon što je pričvršćenMožete postaviti točke prekida na određenim funkcijama (na primjer break checkFirmware), nastaviti izvršavanje i pustiti da normalan tok programa (na primjer, prijenos firmvera s web sučelja) aktivira točku prekida.

Korištenje gdbservera s WinDbg-om na Linuxu

Posljednjih godina Microsoft je dodao podršku za otklanjanje pogrešaka u Linux procesima u WinDbg-u. Korištenje gdbservera kao pozadinskog sustava. Ova funkcionalnost namijenjena je scenarijima u kojima radite u sustavu Windows, ali se kod izvršava na Linuxu (uključujući WSL).

Za otklanjanje grešaka u određenom Linux procesu pomoću WinDbg-a pomoću gdbserveraTijek bi bio otprilike ovakav: prvo locirate ciljni proces na Linux računalu pomoću naredbe poput ps -A (na primjer a python3 koji se izvodi), zatim pokrećete gdbserver na cilju:

Naredba: gdbserver localhost:1234 python3

Ako okruženje to zahtijeva, možda ćete morati koristiti sudo gdbserver ...s istim sigurnosnim mjerama opreza kao i uvijek. Nakon što gdbserver označi da "Sluša na portu 1234", u WinDbg-u idite na "Datoteka / Poveži se s udaljenim programom za ispravljanje pogrešaka" i navedite niz za povezivanje sljedećeg tipa:

Naredba: gdb:server=localhost,port=1234

WinDbg koristi mali "upravljački program" za gdb protokol za komunikaciju s gdbserverom i, nakon što je veza uspostavljena, ostaje zaustavljena na mjestu čizma procesa. Odatle možete koristiti njegove prozore stoga, module, memoriju, točke prekida, kao i naredbe poput k vidjeti bateriju ili lm za popis modula (imajući na umu da neke naredbe očekuju PE format, a ne ELF, pa u određenim slučajevima mogu prikazati čudne podatke).

gdbserver i WinDbg procesni poslužitelj

Osim slučaja s jednim procesom, WinDbg se može povezati s gdbserverom koji djeluje kao procesni server. da radi sličnije načinu rada s udaljenim Windows procesima. U ovom načinu rada, gdbserver se pokreće s --multi i bez pridruženog procesa:

  Najbolji način za aktiviranje načina niske potrošnje energije na iPhoneu

Naredba: sudo gdbserver --multi localhost:1234

Iz WinDbg-a odaberite "Datoteka / Poveži se s procesnim poslužiteljem" i ponovno koristite niz za povezivanje gdb:server=localhost,port=1234Kada je veza aktivna, možete navesti dostupne Linux procese i pridružiti se onome koji želite ili čak pokrenuti novi proces.

Treba imati na umu jedan suptilan detalj.WinDbg razlikuje "poslužitelj procesa" i "jedan cilj" ovisno o tome je li gdbserver već priključen na proces kada se poveže. Ako ste ostavili gdbserver priključen na proces, zatvorili WinDbg, a zatim pokušali ponovno povezati se, možda neće biti prepoznat kao poslužitelj procesa i možda ćete morati ponovno pokrenuti gdbserver.

Za završetak sesije procesnog poslužiteljaObično je dovoljno jednostavno pritisnuti CTRL+D u konzoli gdje se izvodi gdbserver i zaustaviti ispravljanje pogrešaka iz WinDbg-a. U nekim ekstremnim slučajevima, ako postoje problemi sa sinkronizacijom, možda će biti potrebno potpuno zatvoriti program za ispravljanje pogrešaka i ponovno pokrenuti gdbserver od nule.

Upravljanje simbolima i izvornim kodom pri udaljenom otklanjanju pogrešaka

Jedan od ključeva za praktično udaljeno otklanjanje pogrešaka je dobro razlučivanje simbola i fontova.Bez simbola, navigacija kroz stog ili postavljanje točaka prekida na određenim funkcijama postaje mučenje.

U klasičnim scenarijima gdb + gdbserver, idealno je čuvati kopiju izvršne datoteke sa simbolima na hostu. (neogoljeno) i izvorno stablo. gdb ne zahtijeva da udaljena binarna datoteka sadrži simbole; dovoljno je da lokalna datoteka koju učitavate s file podudara se s udaljenom izvršnom datotekom na razini pomaka.

U svijetu WinDbg-a i Linux debugginga pojavile su se i usluge poput DebugInfoD-a.koji izlažu simbole i fontove putem HTTP-a. WinDbg može koristiti posebne putanje tipa DebugInfoD*https://debuginfod.elfutils.org oba u .sympath kao u .srcpath za preuzimanje DWARF simbola na zahtjev i izvornog koda Linux ELF binarnih datoteka.

U konkretnom primjeru s WSL-om, gdje se korisnički kod nalazi pod C:\Users\Bob\Mogli biste reći WinDbg-u:

Naredba: .sympath C:\Users\Bob\
.srcpath C:\Users\Bob\

A ako također želite koristiti DebugInfoD za sistemske binarne datoteke:

Naredba: .sympath+ DebugInfoD*https://debuginfod.elfutils.org
.srcpath+ DebugInfoD*https://debuginfod.elfutils.org

S ovom konfiguracijom, kada pregledavate stog ili unosite libc funkcijeWinDbg može pokušati preuzeti odgovarajuće DWARF simbole i, ako poslužitelj također otkrije kod, prikazati izvorni kod s priličnom detaljnošću, iako interno Windows alatni lanac ne obrađuje ELF i DWARF tako "izvorno" kao PE i PDB.

Praktični primjer: otklanjanje pogrešaka u C++ programu pomoću gdbservera i WinDbg-a

Ilustrativan primjer je mala C++ aplikacija koja ispisuje pozdrav na ekran., kompiliran u WSL-u sa simbolima za otklanjanje pogrešaka. Zamislite program koji rezervira std::array<wchar_t, 50> i kopira dužu poruku u nju, uzrokujući skraćivanje teksta i pojavljivanje znakova ???? na kraju

Nakon kompajliranja s nečim poput:

Naredba: g++ DisplayGreeting.cpp -g -o DisplayGreeting

Pokrećete gdbserver protiv tog binarnog programa.:

Naredba: gdbserver localhost:1234 DisplayGreeting

U WinDbg-u se povezujete s nizom znakova gdb:server=localhost,port=1234 I, nakon što je sesija uspostavljena i putanje simbola i fontova konfigurirane, postavljate točku prekida u DisplayGreeting!mainmožete koristiti dx greeting pregledati lokalni niz i vidjeti njegovu veličinu (50 pozicija) te vizualno provjeriti u kartici memorije ili u prikazu varijabli kako je pozdrav odrezan.

Ljepota ovog primjera je u tome što pokazuje da, čak i bez pune podrške za sve ELF/DWARF formate u WinDbg-uMožete pregledavati stekove, pregledavati tipove, postavljati točke prekida prema nazivu funkcije i relativno udobno se kretati kroz C++ kod koristeći gdbserver kao udaljeni backend.

Otklanjanje grešaka u Linux kernelu pomoću qemu-a i gdb-a

gdbserver se ne koristi samo u korisničkom načinu rada; postoje i vrlo moćni scenariji u kernel načinu rada.posebno kada kombinirate QEMU s podrškom za otklanjanje pogrešaka. Iako ovdje ulogu "gdbservera" ispunjava QEMU-ova vlastita opcija, pristup je identičan: jedan kraj pokreće sustav koji se otklanja i otvara gdb port; drugi kraj je ili gdb ili debugger koji govori udaljenim protokolom.

Za debugiranje kernela, potrebno ga je kompajlirati s određenim opcijama debugiranja.: aktivirati generiranje informacija za otklanjanje pogrešaka (CONFIG_DEBUG_INFO), skripte GDB kernela (CONFIG_GDB_SCRIPTS) i vlastiti način otklanjanja pogrešaka kernela (CONFIG_DEBUG_KERNELTakođer je važno onemogućiti opcije koje uklanjaju simbole tijekom povezivanja, kao što je "Ukloni simbole generirane asemblerom tijekom povezivanja".

Nakon kompajliranja dobit ćete binarnu datoteku vmlinux "nije ogoljelo"koji ćete koristiti iz gdb-a. Također vam je potreban osnovni initramfs, koji možete generirati naredbom poput:

Naredba: mkinitramfs -o ramdisk.img

Zatim pokrećete QEMU s parametrima za otklanjanje pogrešakaTipičan primjer uključuje opciju -gdb tcp::1234 za otvaranje gdb-kompatibilne udaljene krajnje točke i -S tako da virtualni stroj od početka počinje pauziran. Također navodite kernel s -kernel vmlinux, -initrd ramdisk.img, sjećanje s -m 512 i obično preusmjeravate konzolu na ttyS0 upravljati svime od terminal.

  Kako ažurirati Edge na najnoviju verziju u sustavu Windows 11: cjeloviti vodič korak po korak

S QEMU-om u pritvoru koji čeka gdbS glavnog računala pokrećete gdb koji pokazuje na vmlinux i povezuješ se s target remote localhost:1234Odatle možete postaviti rane točke prekida, na primjer hb start_kerneli kontrolirati izvršavanje naredbama kao što su c (nastavi) i CTRL+C za ponovnu pauzu.

Nedavne promjene i nijanse u gdb-u i gdbserver-u

U modernim distribucijama poput Red Hat Enterprise Linuxa 8, postoji niz promjena u gdb-u i gdbserver-u koje vrijedi imati na umu.pogotovo ako dolazite s prethodnih verzija ili imate skripte koje analiziraju izlaz programa za ispravljanje pogrešaka.

S jedne strane, gdbserver sada pokreće "niže" procese koristeći ljuskuBaš kao i gdb, ovo omogućuje proširenje i zamjene varijabli u naredbenom retku. Ako iz bilo kojeg razloga trebate onemogućiti ovo ponašanje, u RHEL-u 8 postoje posebne postavke dokumentirane za povratak na prethodni način rada.

Nekoliko je stvari također uklonjeno ili promijenjenopodrška za otklanjanje pogrešaka za Java programe kompilirane s gcj, HP-UX XDB način kompatibilnosti, naredbe kao što su set remotebaud (zamijenjeno s set serial baud) ili kompatibilnost s određenim starijim formatom stabsNadalje, numeriranje niti više nije globalno, već po "donjoj" niti i pojavljuje se kao inferior_num.thread_num, s novim praktičnim varijablama kao što su $_gthread za pozivanje na globalni identifikator.

Još jedna relevantna nova značajka je prilagodba max-value-sizeOvo ograničava količinu memorije koju gdb može dodijeliti za prikaz sadržaja vrijednosti. Zadana vrijednost je 64 KiB, pa pokušaji ispisa ogromnih nizova ili masivnih struktura mogu rezultirati upozorenjem "vrijednost je prevelika" umjesto prikaza sve dostupne memorije.

Također je prilagođen način na koji gdb obrađuje sysrootZadana vrijednost je sada target:To znači da će za udaljene procese prvo pokušati pronaći biblioteke i simbole na ciljnom sustavu. Ako želite da se prioritet da lokalnim simbolima, trebali biste pokrenuti set sysroot s rutom koja vas zanima prije nego što krenete target remote.

Što se tiče povijesti naredbi, varijabla okruženja koja se sada koristi je GDBHISTSIZE umjesto da HISTSIZETo vam omogućuje fino podešavanje koliko dugo želite zadržati naredbe koje ste upisali u sesijama otklanjanja pogrešaka bez ometanja ponašanja drugih aplikacija koje koriste biblioteku za čitanje redaka.

Savjeti za tijek rada i rješavanje problema s gdbserverom

Za ugodan tijek rada, postoje neki obrasci koji obično vrlo dobro funkcioniraju. Prilikom razvoja za ugrađene sustave ili udaljene poslužitelje, prvi korak je što veća automatizacija kompilacije simbola i binarnog postavljanja na cilj. Na taj način uvijek znate koja se verzija izvršne datoteke izvodi i imate kopiju simbola lako dostupnu na hostu.

U okruženjima s mnogo jezgri koje uzrokuju pad sustava, vrijedi naučiti kako koristiti gdb u batch načinu rada., sa zastavama poput --batch, --ex y -x za automatsko pokretanje naredbi na popisu jezgri i obradu njihovih povratnih tragova iz skripti (na primjer u PitonTo vam omogućuje brzo filtriranje ponovljenih problema, grupiranje kvarova prema tragu stoga itd.

Kada nešto pođe po zlu s udaljenom vezom, opcija --debug gdbserver je tvoj najbolji prijateljAko pokrenete, na primjer, procesni poslužitelj sa:

Naredba: gdbserver --debug --multi localhost:1234

Konzola gdbservera će prikazati detaljne tragove onoga što se događa Na razini udaljenog protokola, to uključuje dolazne pakete, pogreške u formatiranju, probleme s prekidom veze itd. Ovo je vrlo korisno kada se vaš gdb poslužitelj iznenada prekine, proces se sruši čim se postavi točka prekida ili vaš debug GUI pošalje nešto što gdbserver ne razumije.

U kontekstima kao što je TP-Link usmjerivač gdje spajate gdbserver na kritični proces poput httpdRelativno je uobičajeno da određene točke prekida stvaraju uvjete utrke ili nadzorne mehanizme koji prekidaju proces kada predugo ostane "zaglavljen" u programu za ispravljanje pogrešaka. U tim situacijama može biti potrebno prilagoditi koji su signali blokirani, koje su niti kontrolirane i, ako je primjenjivo, izmijeniti samu konfiguraciju sustava (vremena čekanja, hardverske nadzorne mehanizme) kako bi se omogućile dulje sesije ispravljanja pogrešaka.

Dobro korištenje gdbservera uključuje kombiniranje nekoliko dijelovaKompajlirajte s odgovarajućim simbolima, odaberite ispravan gdb za arhitekturu, konfigurirajte putanje simbola i izvora, shvatite dva glavna načina rada gdbservera (jednoprocesni i višeprocesni) i ne bojte se izvući iz tog načina rada. --debug kada se veza ne ponaša kako se očekuje. S tom osnovom, otklanjanje pogrešaka u aplikacijama koje se izvode na udaljenom Linux sustavu, usmjerivaču ili virtualnom stroju s prilagođenom jezgrom s vašeg računala postaje prilično rutinsko i, prije svega, nevjerojatno korisno.