Dynamická analýza programu ( dynamická analýza programu nebo DPA ) je forma analýzy programu, která vyžaduje provedení. Umožňuje studovat chování počítačového programu a účinky jeho provádění na jeho prostředí. Při použití ve fyzickém nebo virtuálním prostředí se často používá k profilování programů. Ať už se jedná o načítání informací o době využití procesoru, využití paměti nebo energii vynaložené programem.
Pomáhá také najít problémy v programech. Může například zjistit, zda program přistupuje do zakázaných oblastí paměti , či nikoli , nebo dokonce odhalit chyby v programu pomocí fuzzerů . Může také umožnit ladění programu v reálném čase, což umožňuje kdykoli během jeho provádění sledovat, co se děje v paměti a v procesoru .
Pro analýzu programu jsou k dispozici tři zdroje informací: zdrojový kód , provádění programu a technické údaje programu. Analýza zdrojového kódu je spíše vyhrazena pro statickou analýzu programů, zatímco provádění programu se více používá pro dynamickou analýzu programu. Obecně lze říci, že statická analýza programu musí analyzovat všechny větve zdrojového kódu, zatímco dynamická analýza se zaměřuje pouze na provádění programu se specifickou sadou dat .
Profilování je například součástí dynamické analýzy, protože sleduje části prováděného kódu. Tyto stopy umožňují odvodit dopad programu na různé hardwarové komponenty, na kterých je spuštěn ( procesor , paměť , pevný disk atd.). Vzhledem k tomu, že obvykle 80% času spuštění programu zabírá 20% zdrojového kódu. Použití profilovače umožňuje přesně lokalizovat, kde se těchto 20% nachází. V případě programů, které jsou prováděny paralelně na několika procesorech, umožňuje použití profilovače určit míru paralelizace programu.
Testování a ladění kódu je nezbytné pro jakýkoli jazyk . Na testování lze pohlížet jako na formu dynamické analýzy programu, jehož účelem je detekovat chyby . Zatímco ladicí program analyzuje kód k vyhledání a opravě chyby .
Chcete-li zlepšit rychlost provádění programu, jedním z nástrojů, které může vývojář použít, je statistické profilování ( Sampling profiler ). Pomáhá detekovat horká místa a úzká místa související s výkonem a vede vývojáře k částem programu k optimalizaci .
Níže je uveden příklad minimalistického profilovače napsaného v Ruby od Aarona Pattersona, který jednoduše vysvětlí, jak funguje Sampling Profiler :
def fast; end def slow; sleep(0.1); end def benchmark_me 1000.times { fast } 10.times { slow } end def sample_profiler target = Thread.current # récupère l'environnement d'exécution courant samples = Hash.new(0) # initialise un dictionnaire qui va contenir les noms des fonctions appelées t = Thread.new do # initialise un nouveau thread loop do # boucle infinie sleep 0.0001 # vitesse d'échantillonnage function_name = target.backtrace_locations.first.label # récupère le nom de la fonction en cours d'exécution samples[function_name] += 1 # incrémente le nombre de fois que la fonction a été vue end end yield # execute le code passé dans le bloc t.kill # arrête le thread samples.dup end result = sample_profiler { benchmark_me } p result # => {"sleep"=>6497, "slow"=>1}Jak je vidět výše, když profiler zastaví program, aby se podíval, která funkce je spuštěna, funkce se sleep objeví 6497 krát, ve srovnání s jednou pro funkci slow. Funkce fasttaké benchmark_menebyly ani měřeny. Vývojář tedy získá indikaci funkce, která v jeho programu zabírá nejvíce času.
Ačkoli profiler vzorkování zpomaluje čas provádění programu (protože je nutné zastavit aktuální úkol, aby bylo možné zjistit, která funkce se spouští), nevyžaduje úpravu kódu přímo za běhu nebo proti proudu.
V případě interaktivní aplikace poskytují tradiční profilovače jen málo užitečných údajů o latencích pociťovaných uživatelem. Profiler vrací data o kódu po dobu provádění programu. V případě interaktivního programu (například textového editoru) jsou však oblastmi zájmu oblasti, kde se uživatel pokusí s programem interagovat (pohyb myši, použití klávesnice atd.). Tyto interakce představují velmi nízkou dobu CPU a náklady ve srovnání s celkovou dobou chodu editoru. Proto se neobjevují jako místa k optimalizaci při profilování programu. To je důvod, proč existují latence profilery, které se zaměřují na tato zpomalení.
Při spuštění programu je důležité profilovat využití paměti. Zejména pokud je program určen k dlouhodobému běhu (jako na serveru ) ak zamezení odmítnutí služby . Pro tento typ analýzy se používají typy „přesných profilerů“. To znamená, že profiler, který se dívá přesně na to, kolikrát byla každá funkce volána.
Níže je příklad minimalistického profilovače napsaného v Ruby Aaronem Pattersonem, který jednoduše vysvětlí, jak funguje Exact Profiler :
def fast; end # return immediatly def slow; sleep(0.1); end # return after 0.1 second def benchmark_me 1000.times { fast } # 1000 appels a la fonction fast 10.times { slow } # 10 appels a la fonction slow end def exact_profiler counter = Hash.new(0) # dictionnaire vide tp = TracePoint.new(:call) do |event| # lorsqu'une fonction est appelée counter[event.method_id] += 1 # on l'ajoute dans le dictionnaire end tp.enable # on active le code ci dessus yield # on appelle le code passé dans le bloc tp.disable # on arrête de compter les appels de fonction return counter end result = exact_profiler { benchmark_me } p result # {:benchmark_me=>1, :fast=>1000, :slow=>10}Bez ohledu na použitý jazyk bude tento typ profilovače vyžadovat instrumentaci kódu. Při každém vyvolání nebo ukončení funkce je nutné do programu přidat další instrukce, které měly být provedeny. To může být dramatické pro dobu trvání programu. Může to skončit 10 až 4 000krát pomaleji.
V Javě například Java Profiler (JP) vloží další bytový kód přírůstek na čítači pokaždé, když metoda se nazývá. To změní skutečný čas spuštění kódu a často způsobí problémy se synchronizací ( může se změnit pořadí provádění vláken ), když je spuštěn na vícevláknových aplikacích.
V případě profilovače paměti musí být použity pouze funkce mající vztah s pamětí. Například v případě Valgrind budou funkce malloc a free nahrazeny funkcí, která upozorní Valgrind, že byly volány před jejich spuštěním. Některé z funkcí, které zapisují do paměti, které se běžně používají nebo které Valgrindovi způsobují problémy, jako jsou memcpy nebo strcpy, jsou také vybaveny .
Se vzhledem smartphonů a rozvojem internetu věcí se spotřeba energie stala v posledních letech velmi důležitým tématem. Ačkoli je možné snížit frekvenci procesorů nebo dokonce shromáždit materiální zdroje ke snížení spotřeby služby, přímé snížení spotřeby energie u programů zůstává řešením, které lze použít paralelně.
Profilování energie je jedním z řešení, které mohou pomoci realizovat spotřebu programu. To spočívá v profilování kódu aplikace při hodnocení spotřeby energie, aby bylo možné přidružit spotřebu k pokynům . K měření spotřeby energie, když je spuštěný program, lze použít několik řešení. Například je možné přímo měřit spotřebu pomocí hardwarových komponent , které jsou umístěny přímo před každou ze součástí používaných programem. Není však vždy možné mít přístup k takovým komponentům měření. Další strategie proto spočívá v použití dříve vytvořených modelů spotřeby. Tyto modely musí brát v úvahu hardwarové prvky používané programem, ale také různé stavy těchto komponent.
Energetická analýza je speciální, protože vyžaduje nejen spuštění programu, ale také vyžaduje znalost energetického profilu všech komponent stroje, na kterém pracuje, aby bylo možné přesně vypočítat dopad energie.
Energetická analýza programů je stále velmi komplikovaná, aby bylo možné ji přesně vyhodnotit. Opravdu, i když některé modely umožňují přiblížit se 10% hranici chyby ve srovnání se skutečnou spotřebou, úkol komplikuje několik faktorů. Za prvé je problematické vzít v úvahu skutečnost, že některá zařízení mají mnoho komponent (např. Chytré telefony). Výsledky pak budou lišit různé stavy, které procesor může nabrat (například stav úspory energie) nebo jeho frekvence . Skutečnost, že určité součásti, jako je GPS, jsou aktivní nebo ne, nebo že antény WIFI jsou v přenosu nebo příjmu, jsou také prvky, které je třeba v rovnici zohlednit. Mohou se také lišit bez ohledu na spuštěný program, což dále komplikuje úkol.
V závislosti na použitých technikách lze energetické profilování vidět s více či méně granularitou . Některé technologie se dokonce pokoušejí poskytnout odhad spotřeby energie pro daný řádek kódu.
Analysis of color (nebo Taint analysis in English) is to tint data to in to track their progress in a computer system. Těmito daty mohou být soubory uložené na pevném disku, v proměnných uložených v paměti RAM nebo jakékoli jiné informace cirkulující v jakémkoli hardwarovém registru . Všechny programy, které jsou závislé na zbarvených datech, jsou následně zbarveny.
Lze jej nastavit buď pomocí hardwarových komponent (fyzických nebo pak v emulaci ) přímo implementovaných na stroji, nebo díky softwaru . Nastavením tónovacího systému přímo na materiál je mnohem snazší kontrolovat data, která procházejí každou komponentou. "Například tónování záznamu na úrovni klávesnice je lepší než tónování záznamu ve webovém formuláři." V případě, že škodlivý software (například) se může pokusit se vyhnout detekci tím, že vytvoří háček s (které mění normální fungování programu), které se nazývají před vstup z klávesnice dosáhne webový prohlížeč. " Přidávání fyzických komponent však může být zdlouhavé. A pokud jsou tyto komponenty emulovány, může se zpomalit provoz sledovaného programu. Může existovat několik možných případů použití pro analýzu odstínů:
Analýzy odstínů se řídí zásadami, které diktují jejich chování na základě potřeb uživatelů. Každá zásada má 3 vlastnosti: způsob, jakým je odstín zaveden do programu; jak se šíří do jiného programu během provádění; jak se kontroluje za běhu. Může současně existovat několik zásad barvení.
Mějte na paměti, že analýza odstínů může někdy podléhat falešným pozitivům.
Jedním ze způsobů, jak způsobit, že se v programu objeví chyby, je použití fuzzeru (např. AFL). Tento typ programu obecně nevyžaduje žádnou úpravu zdrojového kódu a vygeneruje náhodné vstupní údaje, aby došlo ke zhroucení kódu . Účinnost fuzzeru se často měří pokrytím kódu, které poskytuje (čím více byl kód proveden, tím lepší je fuzzer ). Tento typ programu, který generuje náhodné vstupy, aniž by měl jiné informace než doby odezvy opačného programu, a pokud došlo k jeho chybě, nazývá se fuzzer black box .
Mnoho fuzzerů, které se často nazývají fuzzery v bílé krabici, používá kombinaci symbolického provedení ( statická analýza ) a dynamické analýzy. Používají symbolické provádění k určení, které parametry se používají k prozkoumání různých větví kódu. Poté se pomocí tradičnějšího fuzzeru vyhledávání chyb provádí normálně.
Například následující kód má šanci 1 z 2 32 na spuštění chyby:
void foo(int c) // la variable que le fuzzer va pouvoir faire varier { if ((c + 2) == 12) abort(); // une erreur }Zadáním ifpodmínky c + 2 == 12není ověřeno, pouze prostřednictvím symbolického provedení je možné určit, že pokud by cse rovnalo 10, program by si vypůjčil druhou větev kódu. Takto fuzzer vybere vhodné hodnoty pro vstup do všech větví programu. To umožňuje, aby se chyby objevovaly rychleji a složitěji.
Běžným způsobem ladění kódu je ruční instrumentace. To znamená, sledovat jeho chování během provádění a přidat výtisky, abyste věděli, co bylo provedeno nebo neprovedeno a kdy byla chyba nalezena. Spuštění programu v debuggeru vám umožní rychle najít zdroj chyby, aniž byste museli upravovat její kód .
Debuggery obvykle umožňují několik operací, když je program spuštěn:
Ale tyto operace nejsou zřejmé, protože kód může být optimalizován kompilátorem . A že mezi optimalizacemi může kompilátor odebrat proměnné nebo změnit uspořádání řádků a ztratit čísla řádků.
Všimněte si, že Microsoft hodně používá fuzzery jako metodu k testování svého kódu. A to natolik, že se z toho stal postup, než jsme mohli uvést jakýkoli kód do výroby.