Debugging i kujtesës në Linux: mjete dhe teknika kryesore

Përditësimi i fundit: 26 Shkurt i 2026
  • Linux ofron komanda të tilla si free, vmstat, ps dhe top për të inspektuar përdorimin aktual të memories dhe CPU-së, duke bërë dallimin midis memories së përdorur, memories së lirë dhe memories së ruajtur në memorje.
  • Mjete si GDB dhe Valgrind ju lejojnë të zbuloni gabimet e segmentimit, rrjedhjet e memories, akseset e paligjshme dhe variablat e painicializuara në programet native.
  • Në mjediset .NET Core, kombinimi i dotnet-dump, LLDB dhe SOS lehtëson analizën e thellë të memory dump-eve si në Linux ashtu edhe në Windows.
  • Një rrjedhë pune diagnostikuese e rregullt që kombinon metrikat e sistemit, regjistrat dhe analizën e dump-eve zvogëlon ndjeshëm kohën për të gjetur dhe korrigjuar problemet e memories.

Debugging i kujtesës në Linux

Kur diçka shkon keq në një server Linux, shkaku shpesh qëndron në mënyrën se si përdoret memoria dhe në mjetet e debugging-ut , por derisa të dini se çfarë të kërkoni, gjithçka duket si një rrëmujë kaotike numrash dhe procesesh. Të kuptuarit e asaj që po ndodh në RAM, si po sillen programet tuaja dhe si të kapni gabimet e memories është çelësi për të shmangur zgjidhjen e verbët të problemeve sa herë që shfaqet një gabim i çuditshëm ose defekt segmentimi.

Në këtë artikull, do të hedhim një vështrim të detajuar dhe të drejtpërdrejtë se si të inspektojmë memorien, të debugojmë programet dhe të analizojmë dump-et në Linux duke përdorur komandat e sistemit (falas, vmstat, /proc/meminfo), debuggers si GDB, analizues memorieje si Valgrind dhe programe ndihmëse specifike për .NET dhe mjedise të tjera. Qëllimi është që ju të dilni me një arsenal praktik për diagnostikimin e problemeve të memories dhe CPU-së në servera dhe mjedise zhvillimi profesional.

Përmbledhje: Memoria në Linux dhe pse nuk duhet të fiksoheni mbi 100%

Në një server Linux, RAM vepron si një ruajtje e shpejtë për të dhënat dhe kodin që sistemi duhet ta ripërdorë së shpejti. Qasja në RAM është shumë më e shpejtë sesa qasja në disk, kështu që kerneli e shfrytëzon këtë për ta përdorur atë si një memorje të përkohshme për skedarët, memorjet e përkohshme dhe faqet e memories që mund të nevojiten përsëri së shpejti.

Në kontekstin e një serveri web që përdor Apache ose Nginx , ose një serveri baze të dhënash si MySQL ose MariaDB, të dish se sa memorie është në përdorim, sa është e lirë dhe sa është e ruajtur në memorje është thelbësore për të përcaktuar siç duhet madhësinë e shërbimeve dhe për të kuptuar hapësirat e emrave dhe grupet c . Në fakt, mjetet e optimizimit si MySQLTuner përdorin këto të dhëna (dhe informacione të tjera) për të sugjeruar cilësimet e buffer-it, memorjes së përkohshme dhe lidhjes.

Është e rëndësishme të kuptohet një koncept që shpesh i habit njerëzit në fillim: RAM-i është projektuar për t'u përdorur . Të shohësh 90% ose edhe 100% përdorim nuk është domosdoshmërisht problem; Linux-i mbush RAM-in me memorie të diskut për të shpejtuar sistemin. Ajo që është vërtet shqetësuese është kur filloni të merrni gabime "mbetja e kujtesës" , procese që rrëzohen me një mesazh OOM (Mbetje pa kujtesë) ose shërbime që ngrijnë, jo thjesht kur grafiku tregon "përdorim të lartë".

Ka kuptim të kaloni në optimizim agresiv vetëm nëse vini re se serveri bëhet i paqëndrueshëm, i ngadaltë ose ndalon shërbimet për shkak të përdorimit të tepërt të memories, ose nëse e dini se po vijnë rritje të trafikut që mund të mbingarkojnë burimet aktuale.

Komandat bazë për inspektimin e memories në Linux

Mjetet e kujtesës në Linux

Hapi i parë në zgjidhjen e problemeve me memorien është të kuptoni RAM-in tuaj total dhe se si ndahet ai midis memories së përdorur, memories së lirë, memories së përkohshme dhe memories së shkëmbimit. Linux ofron disa shërbime për këtë, secila me një nivel të ndryshëm detajesh.

komandë falas: përmbledhje e shpejtë e RAM-it dhe shkëmbimit

Komanda më e përdorur për një shikim të shpejtë është falas, veçanërisht me parametrin -h Për të shfaqur madhësitë në një format të lexueshëm: Për më shumë informacion mbi interpretimin dhe optimizimin e këtyre metrikave, shihni optimizo statistikat e kujtesës.

free -h

Rezultati tipik ju tregon, në disa rreshta, memorien totale, të përdorur, të lirë, të përbashkët, të buffer-it dhe të memorjes cache , si për RAM ashtu edhe për hapësirën swap. Do të shihni diçka të tillë:

buffer-a të përdorur gjithsej të lirë të ndarë të ruajtur në memorje të përkohshme Memoria: 2.0G 1.5G 470M 300M 0B 414M -/+ buffer-a/memorie e përkohshme: 1.1G 885M Shkëmbim: 0B 0B 0B

Linja -/+ buffers/cache Është veçanërisht i dobishëm sepse tregon memorien e përdorur në të vërtetë nga proceset (duke përjashtuar bufferët/memorjet e përkohshme) dhe memorien potencialisht të disponueshme për aplikacione të reja. Shumë njerëz shohin pak "memorie të lirë" në rreshtin e parë dhe alarmohen, kur në realitet shumica e saj është thjesht e ruajtur në memorje dhe mund të... ripërdorur pa dramë.

vmstat: memorie aktive, joaktive dhe metrika të sistemit

Kur keni nevojë për diçka më të detajuar, vmstat ofron një pamje më teknike të sistemit. Me:

vmstat -s -S M

Do të merrni një listë me memorien totale, memorien e përdorur, memorien e lirë, memorien aktive, memorien joaktive, memorjet e përkohshme, memorien e ndërruar, etj. Për shembull:

2048 M memorie totale 1582 M memorie e përdorur 1124 M memorie aktive 406 M memorie joaktive 465 M memorie e lirë 0 M memorie buffer 407 M memorie e përkohshme swap 0 M shkëmbim total 0 M shkëmbim i përdorur 0 M shkëmbim i lirë

Koncepti i memories joaktive është interesant: është memorie që konsiderohet të jetë në përdorim, por nuk shoqërohet me procese aktive, kështu që për qëllime praktike sillet si memorie që sistemi mund ta rikuperojë . Kjo ndihmon në shpjegimin pse Linux mund të duket se "zë të gjithë hapësirën", por, në realitet, ka hapësirë ​​për të liruar kur është e nevojshme.

/proc/meminfo: detajet e papërpunuara të kernelit

Nëse dëshironi të gjitha detajet që trajton kerneli, gjithmonë mund të shikoni skedarin /proc/meminfo :

cat /proc/meminfo

Ky skedar përfshin dhjetëra fusha që lidhen me menaxhimin e memories së brendshme : memorie totale, memorie e lirë, buffera, memorje e përkohshme, slab, hugepages, memorie e disponueshme, etj. Është shumë i dobishëm për mjetet e automatizuara dhe skriptet e monitorimit, megjithëse leximi i tij direkt është disi më pak i lehtë për t’u përdorur sesa `free` ose `vmstat` dhe kërkon një kuptim të plotë të asaj që do të thotë secila fushë.

Panelet e kontrollit dhe "realiteti i tyre paralel"

Nëse menaxhoni një server me panele kontrolli si cPanel, Plesk, VestaCP ose Webmin , do të shihni se ato zakonisht shfaqin grafikë të memories së përdorur, të lirë dhe të ruajtur në memorje të përkohshme përmes një ndërfaqeje interneti. Këto të dhëna janë të përshtatshme, por mbani mend se ato përditësohen periodikisht dhe ndonjëherë nuk pasqyrojnë statusin e saktë në kohë reale. Për diagnostikim të plotë dhe rregullim të imët, është gjithmonë më mirë të përdorni terminalin dhe komandat e tij origjinale.

Debugimi i proceseve dhe memories me mjete sistemi

Pasi të dini se sa memorie është e disponueshme dhe si përdoret ajo në terma të përgjithshëm, hapi tjetër është të gjeni se cilat procese po konsumojnë burime në mënyrë anormale dhe të analizoni sjelljen e tyre. Këtu hyjnë në lojë shërbimet klasike si ps, top, htop, strace dhe ltrace, si dhe komandat e rrjetit dhe të diskut që ndihmojnë në eliminimin e pengesave.

ps, top dhe htop: një rreze X e proceseve dhe CPU-së

Komanda `ps` shfaq proceset aktive. E kombinuar me filtrat dhe renditjen, ju lejon të gjeni shpejt se çfarë po konsumon CPU-në.

ps aux --sort=-%cpu | head

Kjo ju tregon proceset e renditura sipas përqindjes së përdorimit të CPU-së , së bashku me përdorimin e memories, përdoruesit dhe komandës. Është ideale si një pamje e shpejtë për identifikimin e të dyshuarit kryesor kur serveri ka burime të pakta; zotërimi i terminalit ju ndihmon të veproni shpejt.

  Një Udhëzues i Plotë për Fluksin e Zërit: Revolucioni në Dizajnin e Agjentëve të Bisedës

Nga ana tjetër, `top` dhe varianti i tij më vizual `htop` ofrojnë një pamje në kohë reale të proceseve, përdorimit të CPU-së, përdorimit të memories, gjendjes (R, S, D, etj.) dhe mesatares së ngarkesës . Duke filluar `top` me:

top -o %CPU

Mund të përqendroheni te proceset që përdorin më shumë CPU. Përtej numrave, është e rëndësishme të kërkoni modele :

  • Proceset në gjendje R (në ekzekutim) që qëndrojnë të mbërthyer në majë për një kohë të gjatë.
  • Ndryshime të papritura në mesataren e ngarkesës që tregojnë rritje të kohëve të fundit të ngarkesës.
  • Shpërndarja e CPU-së në %us, %sy dhe %wa (koha e përdoruesit, koha e sistemit dhe pritja e hyrjeve/daljeve).
  • Nëse procesi problematik është një shërbim sistemi, një përdorues specifik ose një daemon.
  • Nëse konsumi është i qëndrueshëm ose Shkon lart e poshtë me ritme të shpejta., gjë që mund të tregojë detyra në grup ose trafik të parregullt.

Një vlerë shumë e lartë %wa (pritje I/O) është një tregues se pengesa mund të mos jetë në CPU, por në disk ose në nënsistemin e ruajtjes.

Rishikimi i fijeve të një procesi: top -H

Për aplikacionet me shumë fije (Java, Python, Node, etj.), nuk mjafton të dish se cili proces po konsumon CPU-në; duhet të shohësh se cili fije specifike po del jashtë kontrollit . Me:

top -H -p PID

Ju merrni detajet e secilës fije pune brenda procesit. Nëse njëra prej tyre shfaqet në 100% dhe pjesa tjetër është në gjendje të papërdorur, ka të ngjarë të ketë një cikël të pafund, një problem të çuditshëm bllokimi ose një seksion kritik të projektuar keq në atë pjesë të kodit.

Prioriteti i procesit: i mirë dhe i ripërpunuar

Nëse një proces që kërkon shumë burime është legjitim, por doni ta parandaloni që ai të mbingarkojë pjesën tjetër të sistemit, mund të rregulloni përparësinë e tij (niceness) . Komandat `nice` dhe `renice` ju lejojnë të filloni procese me përparësi më të ulët ose të rregulloni përparësinë e një procesi ekzistues, në mënyrë që kerneli t'u ndajë atyre më pak kohë të CPU-së krahasuar me detyrat e tjera kritike.

Komanda të tjera kryesore: pidof, kill, strace dhe ltrace

Kur sistemi është nën presion, është e dobishme të jesh në gjendje të lokalizosh dhe kontrollosh shpejt proceset:

  • pidofmerr PID-in e një procesi nga emri i tij, perfekt për skripte ose ndërhyrje të shpejta.
  • vras: dërgon sinjale te proceset (TERM, KILL, etj.), ose për t'u mbyllur në mënyrë të rregullt ose për të ndërprerë punën nëse ato kanë ngecur.
  • shtrëngoj: tregon thirrjet e sistemit që kryen një proces; ideal për të parë se ku është mbërthyer (lexime disku, soketa, etj.).
  • gjurmëNgjashëm me strace, por i fokusuar në thirrje në librari, i dobishëm për debugging-un e problemeve të përdorimit të API-t të përbashkët.

Këto mjete nuk janë të dobishme vetëm për gjurmimin e rrjedhjeve ose rrëzimeve të memories, por përdoren gjerësisht edhe në sigurinë kibernetike, analizën mjeko-ligjore dhe debugging-un e sjelljes së çuditshme binare .

Komandat për skedarët dhe diskun: lsof, df, du, locate

Kur dyshoni se diçka nuk shkon me memorien (për shembull, shumë skedarë të hapur ose disqe të mbushura), hyjnë në lojë komanda të tjera:

  • lsof: renditni skedarët e hapur nga një proces, i dobishëm për të gjetur rrjedhje të përshkruesve ose skedarëve që parandalojnë çmontimin e një sistemi skedarësh.
  • df: tregon hapësirë ​​e lirë në disk nga sistemi i skedarëve, thelbësore për të përjashtuar 100% të disqeve që shkaktojnë dështime kaskaduese.
  • du: llogarit hapësirë ​​e përdorur nga drejtoritë, shumë i dobishëm për gjetjen e dosjeve që rriten në mënyrë të pakontrollueshme (log-e, kopje rezervë, etj.).
  • gjetur: ju lejon të kërkoni një skedar sipas emrit duke përdorur një bazë të dhënash të indeksuar, më shpejt sesa gjetja në shumë situata.

Komandat e rrjetit për diagnostikim: nc, netstat, ab, tcpdump, wireshark, nmap

Shpesh, problemet me performancën dhe memorien shoqërohen me bllokime ose sulme në rrjet , kështu që është mirë të keni në dispozicion disa mjete bazë:

  • nc (netcat): një thikë e vërtetë zvicerane për rrjetëzimin; hap prizat, dërgon dhe merr të dhëna, lejon testimin e shërbimit, madje edhe tunelet e improvizuara.
  • netstatShfaq lidhjet aktive, prizat e dëgjimit dhe statistikat e rrjetit, të dobishme për të parë nëse ka shumë lidhje me një port të caktuar.
  • ab (Apache Benchmark)gjeneron një ngarkesë kundër një serveri web për të matur kohën e reagimit dhe sjelljen nën stres.
  • tcpdump dhe Wireshark: kap paketat e rrjetit për të analizoni trafikun në thellësi; tcpdump në tastierë, Wireshark me ndërfaqe grafike.
  • hartaSkaner portesh dhe shërbimesh, i përdorur gjerësisht si për auditimet e sigurisë ashtu edhe për kontrollin e sipërfaqja e ekspozimit të serverit.

GDB: debugger klasik për gabimet e memories dhe rrëzimet në kohën e ekzekutimit

Kur një program Linux rrëzohet për shkak të një defekti segmentimi ose një gabimi tjetër të madh, hapi tjetër logjik është përdorimi i një debugger-i të mirë. Mjeti kryesor në botën e GNU-së është GDB (GNU Debugger) , i cili ju lejon të inspektoni gjendjen e brendshme të një programi, ta ndaloni atë kudo që të dëshironi, të shikoni variablat dhe përdorimin e memories dhe të ndiqni ekzekutimin hap pas hapi.

GDB u projektua fillimisht për programet C dhe C++, por është zgjeruar në gjuhë të tjera si Rust dhe madje edhe Assembly , si dhe në trajtimin e shtigjeve të librarive si LD_LIBRARY_PATH . Është thelbësor në zhvillim, por edhe në sigurinë kibernetike, ku përdoret për inxhinieri të kundërt, gjetjen e dobësive dhe zhvillimin ose debugging-un e shfrytëzimeve.

Nisni GDB dhe ekzekutoni një program

Për të përdorur GDB me një skedar ekzekutues, rekomandohet të kompiloni programin me informacion për debugging duke përdorur opsionin -g nga GCC:

gcc -g -Wall programa.c -o programa

Pastaj e lançoni me:

gdb programa

Brenda GDB, programi nuk është ende në punë. Mund ta nisësh me:

  • të kandidojëNisni programin me çfarëdo argumentesh që dëshironi.
  • Fillimi: njësoj si run, por ndalet në fillim të funksionit main.

Nëse keni një skedar ekzekutues të quajtur, për shembull, Suma Dhe nëse doni të shihni se si i përpunon argumentet e tij, do të shkonit në GDB dhe pastaj do të përdornit run 3 5 për ta nisur atë me ato parametra nga debugger-i.

Pikat e ndërprerjes dhe pikat e vëzhgimit: ndalimi i programit aty ku është e nevojshme

Pikat e ndërprerjes janë pika ndalimi në kodin burimor: kur ekzekutimi arrin ato, programi ndalet dhe ju mund të inspektoni gjendjen e tij të brendshme. Në GDB, ato përcaktohen me komandën :

break lugar

ku "vendndodhja" mund të jetë një emër funksioni, numër rreshti ose file:line . Një shembull tipik do të ishte:

break main

në mënyrë që GDB të ndalet pikërisht kur hyn në funksionin kryesor. Kur programi ndalet në një pikë ndërprerjeje, mund të shikoni kodin me l (listë), të kontrolloni variablat dhe të lundroni në grumbullin e thirrjeve.

Pikat e mbikëqyrjes funksionojnë ndryshe: në vend që të ndalen në një pikë specifike në kod, ato ndalen kur vlera e një variabli ndryshon . Ato janë shumë të dobishme për zbulimin e dëmtimit të memories ose modifikimeve të papritura në strukturat kritike pa pasur nevojë ta mbingarkojnë kodin me deklarata printimi.

Kontroll i imët i rrjedhës: hapi, tjetri, vazhdo, mbaro

Pasi programi të ndalet në një pikë ndalimi, keni disa mënyra për të vazhduar:

  • hap: ekzekuton rreshtin e mëposhtëm dhe fut funksionet e thirrura.
  • tjetër: ekzekuton rreshtin e mëposhtëm pa futur funksionet (i ekzekuton ato "të gjitha menjëherë").
  • vazhdoj: rifillon ekzekutimin deri në pikën tjetër të ndërprerjes ose derisa programi të përfundojë.
  • fund: vazhdon derisa funksioni aktual të kthehet dhe të shkojë përsëri në pikën nga ku është thirrur.
  Udhëzues i plotë për platformat e dizajnit vizual për agjentët bisedorë dhe inteligjencën artificiale gjeneruese

Kjo ju lejon të inspektoni kodin e dyshimtë hap pas hapi, pa pasur nevojë ta "gëlltisni" të gjithë programin. Një truk i dobishëm: në GDB, Shtypja e Enter përsërit komandën e funditideale për të bërë shumë next o step e ndjekur nga më pak shtypje.

Stack dhe frame-e thirrjeve: shikoni si arritëm këtu

Për të kuptuar pse ndodhi një dështim në një pikë të caktuar, është thelbësore të shihet se cilat funksione u thirrën deri në atë pikë. Struktura që ruan këtë informacion është grumbulli i thirrjeve . GDB ofron disa komanda për menaxhimin e tij:

  • bt (gjurmim prapa): tregon të gjithë pirgun, me listën e funksioneve të ndërthurura dhe numrat e kornizave.
  • up: lëviz një nivel më lart në pirg, deri në pikën ku thirret funksioni aktual.
  • poshtë: zbret një nivel poshtë, te funksioni që ishte duke u ekzekutuar.
  • fr (kornizë): shfaq kuadrin aktual ose ju lejon të kaloni në një tjetër duke treguar numrin e tij.

Kjo ju lejon të pozicionoheni në nivele të ndryshme të thirrjes (për shembull, duke kaluar nga një funksion i brendshëm në main ) dhe të shihni se si ishin variablat në secilin vend.

Ndërveprimi me kujtesën: vendos, kthe, gjurmim prapa yx

Një nga avantazhet e mëdha të GDB është se ju lejon të lexoni dhe modifikoni memorien ndërsa programi është i ndaluar. Disa operacione të dobishme përfshijnë:

  • i vendosur: ndryshon vlerën e një variabli gjatë ekzekutimit, ideale për testimin e skenarëve pa rikompilim.
  • vlera e kthimit: detyron funksionin aktual të kthejë vlerën e specifikuar, pa vazhduar të ekzekutojë kodin e tij.
  • gjurmë prapa: tashmë e parë, për të treguar grumbullin aktual të thirrjeve.
  • xshqyrton përmbajtjen e memories duke filluar nga një adresë, me formate dhe madhësi të ndryshme (për shembull, x/4xw 0x7fffffffe000 për të parë katër fjalë në heksadecimal).

Me këto opsione mund të replikoni gabime, të kontrolloni nëse një input i rrezikshëm shkakton një mbingarkesë ose të inspektoni strukturat komplekse të të dhënave në stick ose heap.

Debugging pas vdekjes me dumps bazë

Linux mund të gjenerojë një skedar bazë kur një proces rrëzohet për shkak të një sinjali si SIGSEGV. Ky skedar përmban gjendjen e plotë të procesit në kohën e rrëzimit: memorien, regjistrat, stivën, etj. Për ta aktivizuar atë në një seancë, thjesht:

ulimit -c unlimited

Për t'i aktivizuar ato në mënyrë më të përhershme për përdoruesit, mund të modifikoni /etc/security/limits.conf dhe të shtoni një rresht si ky:

* soft core unlimited

Kur një program rrëzohet, ai gjeneron një skedar që zakonisht quhet "core" në direktorinë e punës. Pastaj mund ta analizoni atë me GDB si kjo:

gdb ejecutable core

Kjo ju lejon të kryeni një analizë post-mortem pothuajse sikur programi të ishte ende aktiv, ideale kur dështimi nuk është lehtësisht i riprodhueshëm sipas kërkesës.

Valgrind: kërkimi për rrjedhje dhe gabime të memories

Për shumë probleme me memorien në C/C++ (dhe gjuhë të ngjashme), GDB është i pamjaftueshëm sepse nuk është projektuar për të zbuluar automatikisht leximet e paligjshme, rrjedhjet ose përdorimin e painicializuar të memories . Këtu hyn në lojë Valgrind - një sistem debugging dhe profilizimi që imiton procesorin dhe monitoron çdo akses në memorie.

Valgrind përfshin disa mjete, por më i përdoruri është Memcheck , i cili zëvendëson menaxherin standard të memories së C me të vetin, duke paraqitur zona mbrojtjeje rreth blloqeve të alokuara . Kjo i lejon atij të zbulojë:

  • Përdorimi i memories së painicializuar (variablat që përdoren përpara se t'u caktohet një vlerë).
  • Lexime/shkrime pas kryerjes së aktiviteteve të lira (përdoret-pas-pa pagesë).
  • Qasja jashtë kufijve të një blloku memorieje.
  • Rrjedhjet e kujtesës (malloc pa pagesë, pointerë të humbur, etj.).

Shembull pa gabime: program "i pastër" nën Memcheck

Supozoni se po përpiloni një program të vogël "përshëndetje botë" me informacion për debugging:

gcc -Wall -gstabs valgrind_hello_good.c -o valgrind_hello_good

Nëse e ekzekutoni nën Valgrind me:

valgrind --tool=memcheck --leak-check=full -v ./valgrind_hello_good

Do të merrni një gjurmë ku, në fund, PËRMBLEDHJA E GABIMIT tregon 0 gabime dhe nuk raportohen rrjedhje. Kjo vërteton se, të paktën nga pikëpamja e Memcheck, programi nuk shfaq anomali të memories.

Zbuloni rrjedhjet e memories

Nëse e modifikoni kodin për të bërë një malloc pa e liruar (për shembull, duke rezervuar një bajt dhe duke mos e liruar kurrë atë) dhe e rikompiloni:

gcc -Wall -gstabs valgrind_hello_bad.c -o valgrind_hello_bad

kur vrapon:

valgrind --tool=memcheck --leak-check=full -v ./valgrind_hello_bad

Valgrind do të shfaqë një PËRMBLEDHJE TË HEAP me një vlerë jo-zero "në përdorim në dalje", duke treguar sasinë e memories së palëshuar. Përveç kësaj, seksioni "definitivisht i humbur" do të tregojë numrin e bajteve dhe blloqeve të rrjedhura, së bashku me gjurmën e thirrjes që shkaktoi rrjedhjen (funksioni, skedari dhe rreshti i kodit).

Për raste më komplekse, ku përdoren filtra, për shembull, 100 bajt në një funksion leak()Dalja nga Valgrind do t'ju tregojë qartë për në malloc problematike, duke lejuar shtimin e free korresponduese dhe verifikoni më pas që përmbledhja të kthehet në zero rrjedhje.

Veprime të paligjshme dhe akses jashtë rrezes së veprimit

Një tjetër gabim tipik që zbulon Memcheck është shkrimi në adresa të pavlefshme , për shembull, shkrimi në vendndodhjen e memories 0 (NULL) ose përtej fundit të një vargu. Nëse kompiloni një program që kryen një shkrim të paligjshëm:

gcc -gstabs -Wall valgrind_illegal_read_write.c -o valgrind_illegal_read_write

dhe e ekzekutoni atë me:

valgrind -v ./valgrind_illegal_read_write

Do të shihni mesazhe si:

Shkrim i pavlefshëm i madhësisë 4 në 0x80483C4: main (valgrind_illegal_read_write.c:8) Adresa 0x0 nuk është e grumbulluar, e mallocuar ose (së fundmi) e liruar.

Kjo ju tregon saktësisht se ku ndodhi shkrimi i paligjshëm dhe sa i madh ishte, diçka që në ekzekutimet normale zakonisht manifestohet si një "Gabim Segmentimi" i thjeshtë pa ndonjë të dhënë të mëtejshme.

Variablat e painicializuara dhe varësitë e tyre nga vlerat

Memcheck gjithashtu ju njofton kur një Vendimi i kontrollit varet nga një ndryshore e painicializuarNëse kompiloni një program me një variabël lokal që nuk inicializohet kurrë dhe përdoret në një if:

gcc -gstabs -Wall valgrind_unitialized.c -o valgrind_unitialized

dhe e ekzekutoni me:

valgrind -v --track-origins=yes ./valgrind_unitialized

Dalja do të përmbajë diçka si:

Kërcimi ose lëvizja e kushtëzuar varet nga vlerat e painicializuara në 0x80483F2: main (valgrind_unitialized.c:9) Vlera e painicializuar u krijua nga një alokim i pirgut në 0x80483EA: main (valgrind_unitialized.c:7)

Parametri –track-origins=yes ndihmon në gjetjen e vendit ku është krijuar për herë të parë variabli i painicializuar, gjë që përshpejton shumë korrigjimin e kodit.

Keqpërdorimi i zbulimit të lirë dhe gabimit në heap

Valgrind gjithashtu vërteton se free thirret vetëm në tregues të vlefshëmNëse përpiqeni të lironi memorie që nuk vjen nga mallocOse nëse klikoni dy herë mbi të njëjtin bllok, do të merrni mesazhe si ky:

free() / delete / delete[] / realloc() i pavlefshëm në 0x402B06C: free (...) nga 0x8048449: main (valgrind_illegal_free.c:11)

Në shumë raste, madje ju tregon se adresa nga e cila po telefononi free Ndodhet menjëherë pas një blloku që është liruar tashmë, duke lejuar identifikimin. gabime në llogaritjen e treguesit ose lëshime të dyfishta.

  Siguri e avancuar në Linux: një udhëzues i plotë për mbrojtjen e sistemeve dhe serverëve

Si përmbledhje, Valgrind është një mjet thelbësor kur dyshoni për rrjedhje të memories, çlirim pas përdorimit ose korruptim të memories në programet native, dhe përdorimi i tij i kombinuar me GDB ofron një pamje shumë të fuqishme të gjendjes së brendshme të aplikacioneve.

Dump-et dhe analizat kryesore në Linux dhe Windows

Në aplikacionet moderne, veçanërisht në .NET Core , analizimi i problemeve komplekse të memories ose performancës shpesh përfshin kapjen e të dhënave të memories për analiza të kujdesshme në një makinë tjetër. Këto të dhëna e ngrijnë gjendjen e procesit në një moment specifik në kohë, njësoj si një dokument tradicional i të dhënave të bërthamës.

Analizimi i .NET dump-eve në Linux me dotnet-dump dhe LLDB

Në mjediset .NET Core në Linux, një nga mjetet e rekomanduara është dotnet-dump . Pas kapjes së një dump, mund të filloni analizën me:

dotnet-dump analyze <dump-file>

Është e rëndësishme që analiza të kryhet në një makinë me të njëjtën arkitekturë dhe shpërndarje Linux si mjedisi ku u gjenerua dump-i. dotnet-dump është i orientuar drejt kodit të menaxhuar .NET; për të analizuar edhe kodin vendas (C/C++), është më e përshtatshme të përdoret LLDB së bashku me zgjerimin SOS.

LLDB ju lejon të debugoni si kodin e menaxhuar ashtu edhe atë vendas, dhe me ndihmën e dotnet-sos mund të instaloni zgjerimin SOS, i cili ofron komanda specifike për .NET. Për të ngarkuar saktë një skedar dump .NET Core, LLDB dhe SOS kërkojnë disa skedarë binare nga mjedisi ku u krijua skedari dump:

  1. libmscordaccore.so
  2. libcoreclr.so
  3. dotnet (hosti i përdorur për të nisur aplikacionin)

Këto skedarë binare zakonisht mund të shkarkohen duke përdorur mjetin dotnet-symbol . Nëse është një ndërtim privat ose nuk janë në serverin e simboleve, gjithmonë mund t'i kopjoni nga makina origjinale. Nëse skedarët binare nuk përfshihen me skedarin dump, mund të përdorni sa vijon në LLDB/SOS:

  • setclrpath <ruta> për të treguar se ku ndodhen skedarët binare .NET Core.
  • setsymbolserver -directory <ruta> për të specifikuar vendndodhjen e simboleve.

Pasi të keni gjithçka që ju nevojitet, ngarkoni skedarin dump në LLDB, duke specifikuar hostin dotnet si skedarin ekzekutues për debugim:

lldb --core <dump-file> <host-program>

Këtu Është rruga për në hedhjen e mbeturinave dhe Zakonisht është binar. dotnet, përveç nëse është një aplikacion i pavarur, në të cilin rast do të ishte skedari ekzekutues i vetë aplikacionit (pa prapashtesën .dll).

Brenda LLDB, shpesh është e nevojshme të konfigurohet serveri i saktë i simboleve me setsymbolserver -ms për të përdorur serverin e Microsoft-it, ose setsymbolserver -directory <ruta> për një drejtori lokale dhe ekzekutoni loadsymbols për të ngarkuar simbolet vendase. Nga aty, mund të përdorni komandat e zakonshme SOS për të analizuar heap-in e menaxhuar, fijet, përjashtimet etj.

Analiza e dump-eve të Linux nga Windows

Dump-et e gjeneruara në Linux nuk kufizohen vetëm në analizimin e tyre në të njëjtin sistem; ato mund të hapen edhe nga Windows me mjete të tilla si Visual Studio, WinDbg ose dotnet-dump. Kapacitetet ndryshojnë:

  • Visual Studio: lejon pastrimin e mbeturinave me një përzierje të kod vendas dhe i menaxhuarme një ndërfaqe grafike shumë miqësore për përdoruesit. Rekomandohet të rishikoni udhëzuesin specifik për Debugimi i të dhënave të memories së Visual Studio.
  • windbgMbështetje e avancuar për skedarët e përdoruesve, duke përfshirë Të dhënat e Linux-it me një rrjedhë pune të ngjashme me Windows. Duhet të përdorni versionin x64 të WinDbg për dump-et nga mjediset Linux x64 ose Arm64, dhe versionin x86 për dump-et x86.
  • dotnet-dump Në Windows: përdoret në të njëjtën mënyrë si në Linux, me dotnet-dump analyzeMos harroni të zgjidhni versionin x64 ose x86 të mjetit sipas arkitekturës së dump-it.

Diagnostikim profesional i përdorimit të lartë të CPU-së dhe memories

Përtej mjeteve specifike, pastrimi i memories në Linux zakonisht përfshin një rrjedhë pune të strukturuar për të shmangur veprimet e rastësishme. Një skemë praktike për serverat është si më poshtë:

  • Shiko më i lartë për të zbuluar modele dhe procese të dyshimta ngarkimi.
  • Konfirmo me ps Proceset që përdorin më shumë CPU dhe memorie.
  • Kontrolloni nëse konsumi është logjik (përpilime, grupe, indeksime) apo duket si sjellje anormale.
  • Analizoni fijet me top -H -p PID kur bëhet fjalë për procese me shumë fije.
  • Për të shqyrtuar regjistrat e shërbimit me journalctl ose bisht.
  • Kontrolloni nëse problemi lidhet vërtet me CPU-në apo është i fshehur në... Hyrje/Dalje në disk duke përdorur iostat.

Për të përcaktuar nëse pengesa është te CPU-ja apo te disku, iostat -xz 1 3 është shumë e dobishme: nëse shihni disqe me shfrytëzim të lartë dhe kohë të gjata pritjeje, së bashku me një %wa të lartë në top , problemi ndoshta nuk është te CPU-ja, por te hapësira e ruajtjes.

Duke aplikuar këtë rrjedhë pune, është më e lehtë të diagnostikohen raste të tilla si:

  • Bote ose trafik keqdashës duke shkaktuar procese php-fpm dhe duke mbingarkuar serverin web.
  • Un Mikroshërbimi Java me një fije në një lak të pafundëm duke konsumuar një bërthamë të tërë.
  • Një proces Python që duket i lidhur me CPU-në, por në të vërtetë është i bllokuar duke pritur për diskun në çdo iteracion të një cikli.

Duke kombinuar mjetet e sistemit (ps, top, vmstat, free), debuggers (GDB, LLDB, dotnet-dump), analizues të memories (Valgrind) dhe komanda të rrjetit dhe diskut, mund të krijoni një mënyrë pune ku problemet e memories dhe të performancës në Linux pushojnë së qeni një kuti e zezë dhe bëhen diçka që, me metodë dhe durim, mund të identifikohet dhe korrigjohet me saktësi të konsiderueshme.

monitor i avancuar i sistemit për linux
Artikuj të ngjashëm:
Monitor i Avancuar i Sistemit për Linux: Një Udhëzues i Plotë