Valgrind | |
---|---|
Sorts | Profiler , felsökare för minnesanvändning |
Författare | Seward, Julian [1] |
Utvecklaren | Valgrind utvecklare |
Skrivet i | C [3] |
Operativ system | Linux , Mac OS X , Android [2] |
senaste versionen | 3.19.0 ( 11 april 2022 ) |
Licens | GNU General Public License |
Hemsida | valgrind.org |
Valgrind är ett verktyg för att felsöka minnesanvändning , upptäcka minnesläckor och profilering . Namnet valgrind är hämtat från nordisk mytologi , där det är namnet på huvudentrén till Valhalla [4] .
Valgrind skapades ursprungligen som ett gratis verktyg för att felsöka minnesanvändning på operativsystemet x86 Linux , men har utvecklats till ett allmänt ramverk för att bygga verktyg för dynamisk minnesanvändningsanalys, trådsäkerhetstestning och profilering. Används i många Linux-baserade projekt [5] . Sedan version 3.5 fungerar Valgrind även under Mac OS X.
Den ursprungliga författaren till Valgrind var Julian Seward , som vann en andra Google - O'Reilly Open Source Award 2006 för sitt arbete med Valgrind [6] [7] . Många andra gjorde också betydande bidrag, inklusive Cherion Armor-Brown, Jeremy Fitzhardin, Tom Hughes, Nicholas Nethercoat, Paul Mackerras, Dirk Muller, Bart Van Assch, Joseph Weidendorfer och Robert Walsh [8] .
Valgrind är fri programvara licensierad under GPL .
Valgrind är i huvudsak en virtuell maskin som använder JIT -kompileringsmetoder, bland annat dynamisk omkompilering . Det vill säga att det ursprungliga programmet inte körs direkt på huvudprocessorn . Istället översätter Valgrind först programmet till en tillfällig, enklare form som kallas en Intermediate Representation (IR), som i sig är processoroberoende och i SSA- form. När det väl har konverterats kan verktyget (se nedan) utföra all nödvändig IR-konvertering innan Valgrind översätter IR tillbaka till maskinkod och låter huvudprocessorn utföra den. Den används även om dynamisk översättning kan användas för detta (det vill säga när huvud- och målprocessorn tillhör olika arkitekturer). Valgrind kompilerar om binären för att köras på huvud- och målprocessorn (eller dess simulator) med samma arkitektur.
På grund av dessa omvandlingar minskar prestandan avsevärt: vanligtvis körs kod som körs under Valgrind och ett "tomt" (gör ingenting) verktyg 5-10 gånger långsammare jämfört med att exekvera koden direkt; och med vissa verktyg upp till 100 gånger långsammare [9] . IR-formen är dock mycket mer instrumenteringsvänlig än originalet, och det förenklar skrivinstrumenteringen avsevärt, och för de flesta projekt är prestandaförsämring under felsökning inte ett betydande problem.
Valgrind-paketet innehåller många verktyg (vissa extra verktyg ingår inte). Standardverktyget (och mest använda) är Memcheck . Runt nästan alla instruktioner infogar Memcheck ytterligare instrumenteringskod som håller reda på laglighet (allt oallokerat minne markeras initialt som ogiltigt eller "obestämt" tills det initieras till ett av de definierade tillstånden, troligen från ett annat minne) och adresserbarhet (om minnet är är föremål för den specificerade adresstilldelningen, det vill säga om den är tom) av minnesoperationer, som lagras i de så kallade V-bitarna respektive A-bitarna . När data flyttas och manipuleras håller instrumentkoden reda på A- och V-bitarnas värden så att de alltid är korrekta på enbitsnivån.
Dessutom ersätter Memcheck standard C - minnestilldelningen med en egen implementering, som bland annat inkluderar minnesskydd runt alla allokerade block (som har A-bitar markerade som "ogiltiga"). Denna funktion gör det möjligt för Memcheck att upptäcka buffertöverflöden av en gång , där programmet läser eller skriver minne utanför det tilldelade blocket (med lite överflöde). (Ett annat sätt att lösa det här problemet är att implementera gränspekare i kompilatorn, vilket minskar risken för oupptäckta fel något, särskilt i stack -allokerat minne snarare än heap -allokerat minne, men det kräver omkompilering av alla instrumenterade binära filer.) Problem som kan detektera Memcheck inkluderar:
Priset för detta är förlust av prestanda. Program som körs under Memcheck tenderar att köras 5-12 gånger långsammare än när de körs utan Valgrind, och de använder också mer minne (på grund av att man tilldelar en betydande minneskostnad). Därför körs koden sällan konstant under Memcheck / Valgrind. Den vanligaste situationen är när de antingen spårar något specifikt fel, eller kontrollerar att det inte finns några dolda fel av vissa typer i koden.
Förutom Memcheck har Valgrind andra verktyg också.
Enligt dokumentationen för version 3.4.0 stöder Valgrind Linux för x86 , x86-64 och PowerPC-arkitekturer . Stöd för Mac OS X lades till i version 3.5.0 [11] . Det finns inofficiella portar till andra UNIX-liknande plattformar (som FreeBSD [12] , NetBSD [13] och QNX [14] ).
Förutom prestandabegränsningen är en betydande begränsning av Memcheck dess oförmåga att upptäcka gränsfel vid användning av statisk eller staplad data [15] . Följande kod kommer att klara Memcheck utan några varningar, oavsett de angivna felen:
int Static [ 5 ]; int func ( void ) { int Stack [ 5 ]; Statisk [ 5 ] = 0 ; /* Fel - endast Static[0] finns före Static[4], Static[5] är utanför arrayen */ Stack [ 5 ] = 0 ; /* Fel - endast Stack[0] finns före Stack[4], Stack[5] är utanför arrayen */ returnera 0 ; }Behovet av att upptäcka denna typ av fel är särskilt viktigt på grund av vissa stackmanipulationsbuggar , vilket gör programvaran sårbar för den klassiska stackbusting-exploateringen .
Det experimentella SGCheck- verktyget för Valgrind är dock ganska kapabelt att upptäcka sådana fel.
Profilerare | |
---|---|
|