• No results found

Hur kan BPSA vidareutvecklas?

Projektgruppen har identifierat tre olika sätt att vidareutveckla programmet, men det finns självklart fler sätt. De fyra saker som går att vidareutveckla är:

• Skriva om verktyget i ett snabbare programmeringsspråk.

• Implementera kundens önskemål om att identifiera om en loop alltid kör ett visst antal iterationer.

• Implementera kundens önskemål om att kunna identifiera vilka delar i ett program som körts och inte körts.

A

Visuell analys av programkod av

Sebastian Broman

A.1

Introduktion

En stor del av kostnaden för att utveckla mjukvara är underhåll och programförståelse. BPSA analyserar assemblerkod och skapar en trädstruktur som dels kan visa vilka vägar program- kod skulle kunna ta eller hur koden exekverats. I verktyget visualiseras trädstrukturerna med hjälp av en TreeView i TkInter som i figur 5.3. För att få en större överblick över ett program kan trädstrukturerna visualiseras i olika grafer. En anropsgraf visar anrop till funk- tioner under en körning och ett flödesschema visar de vägar programmet skulle kunna ta. Från graferna går det att räkna ut cyklomatisk komplexitet och maxdjup.

A.1.1

Syfte

Syftet med denna rapport är att analysera grafer skapade från trädstrukturerna genererade i BPSA och vad de graferna kan indikera om programkoden, samt att beskriva vad trädstruk- turerna går att använda till.

A.1.2

Frågeställningar

1. Hur kan BPSA modifieras för att rita en anropsgraf? 2. Hur kan BPSA modifieras för att rita ett flödesschema?

3. Hur kan en anropsgraf tillsammans med ett flödesschema användas för att förstå pro- gramkod?

A.2

Bakgrund

Kostnaden av underhåll är över 90 % av den totala kostnaden för utveckling av mjukvara [26]. En stor anledning till att underhåll är kostsamt är på grund av förståelse över hur pro- gram fungerar. Tid som läggs på förståelse av hur program fungerar står för mer än 50 % av underhållskostnaden. [27]

Ett stort problem inom underhåll är att en utvecklare som ska underhålla en del av ett system förmodligen har bra koll på den delen av systemet, men har inte nödvändigtvis koll

A.3. Teori

på hur den delen påverkar andra delar av systemet. Grafiska representationer av ett system visar tydligt hur delsystem hänger ihop och vilka delar av ett system som är centrala. [28]

A.3

Teori

A.3.1

Visuella verktyg för förståelse av programkod

I en undersökning [29] av S. Bassil och R. K. Keller om olika mjukvaruvisualiseringsverktyg fann de följande fördelar:

• Spara tid genom att utföra vissa uppgifter med mjukvaruvisualiseringsverktyg. • Bättre kodförståelse.

• Ökad produktivitet. • Hantering av komplexitet. • Hjälp att hitta buggar i kod. • Förbättringar i kvalitet.

Bland deltagarna i undersökningen var möjligheten att rita anropsgrafer en av de viktigaste funktionerna hos ett mjukvaruvisualiseringsverktyg en annan viktig funktion var att visua- lisera arv mellan klasser i objektorienterade språk. 68 % av deltagarna ansåg att mjukvaruvi- sualiseringsverktygen gav användbar information. [29]

A.3.2

Graphviz

Graphviz är program som kan utifrån text automatiskt generera grafer och spara de i fle- ra olika filformat bland annat PNG (Portable Network Graphics) och SVG (Scalable Vector Graphics). Det finns stöd för flera olika algoritmer som placerar noder på olika sätt. [30]

A.3.3

Flödesschema

Ett flödesschema är en graf som visar vilka möjliga vägar ett program kan ta. Varje nod be- står av ett kodsegment som alltid körs i ordnad rak följd. Kanterna i grafen är de hopp som programmet skulle kunna göra. [31]

A.3.4

Anropsgraf

En anropsgraf är en graf över ett program där varje nod representerar en funktion och varje kant representerar funktionsanrop [32]. Anropsgrafer kan genereras statiskt från programkod eller dynamiskt från en eller flera körningar av ett program. Dynamiska anropsgrafer visar den del av programmet som körts, statiska anropsgrafer kan istället visa kod som aldrig kan nås. [33]

A.3.5

Cyklomatisk komplexitet

Den cyklomatiska komplexiteten för en graf där e är antalet kanter, n antalet noder och p antalet ihopkopplade komponenter är definierat som:

V(G) =e ´ n+2p

Ett alternativt sätt att räkna ut den cyklomatiska komplexiteten där v är antalet noder i grafen med högre än 1 i gradtal är:

A.4. Metod

Den cyklomatiska komplexiteten hos ett flödesschema över en funktion kan ses som ett mått på funktionens komplexitet. [31]

Cyklomatisk komplexitet har kopplats till felsäkerhet, läsbarhet och testbarhet hos funk- tioner. En funktion med låg cyklomatisk komplexitet kan modifieras med mindre risk att skapa en bugg än en funktion med hög cyklomatisk komplexitet. I tabell A.1 [34] presente- ras riktmärken för olika nivåer av komplexitet hos funktioner och en uppskattad risk med komplexiteten. I tabellen beskrivs olika typer av funktioner där funktioner som har högre än 50 i cyklomatisk komplexitet bedöms vara omöjliga att testa. Vissa metoder kan vara enkla men ändå få hög cyklomatisk komplexitet exempelvis olika switch-satser med många olika fall. [34]

Komplexitet V(G) Typ av funktion Risknivå

1-4 Enkel Låg

5-10 Normal Låg

11-20 Komplex Måttlig

21-50 Komplex Hög

>50 Otestbar Väldigt hög

Tabell A.1: Riktmärken för cyklomatisk komplexitet

A.3.6

Klusterkoefficient

Klusterkoefficienten är en egenskap hos noder i en graf som mäter hur många av nodens grannar som också är kopplade till någonting. Ett högt värde på klusterkoefficienten visar att ett område av noder är nära knutna till varandra, vilket är dålig praxis inom mjukvaruut- veckling då det leder till komponenter som är nära knutna till varandra. Om komponenter i en programvara är nära knutna till varandra är det svårare att vidareutveckla den program- varan. [35]

Området Nitill en nod viges enligt [35] av dess grannar,

Ni=tvjeijPE _ ejiPEu.

Vidare ges klusterkoefficienten för noden vidär kiär antalet grannar i området ges av:

Ci=

|tejk : vj, vkPNi, ejkPEu|

ki(ki´1)

A.4

Metod

Rapporten består av två delar, först en litteraturstudie om vad trädstrukturerna skapade i BPSA är, hur de kan presenteras som grafer, olika egenskaper hos graferna och vad de säger om programkoden. En andra del där analyser från BPSA används för att rita grafer utifrån ett exempelprogram samt räkna ut eventuella egenskaper hos graferna.

A.4. Metod 1 void f 1 ( ) { 2 } 3 4 void f 2 ( ) { 5 f 1 ( ) ; 6 } 7 8 void f 3 ( i n t t e s t ) { 9 i f ( t e s t > 0 ) { 10 f 2 ( ) ; 11 } e l s e { 12 f 1 ( ) ; 13 } 14 } 15 16 void r u n _ t e s t ( i n t t e s t ) { 17 f o r ( i n t i = 0 ; i < t e s t ; i + + ) { 18 i f ( i == 1 ) { 19 f 1 ( ) ; 20 } e l s e i f ( i == 2 ) { 21 f 2 ( ) ; 22 } e l s e i f ( i == 3 ) { 23 f 3 ( 0 ) ; 24 } e l s e i f ( i ! = 4 ) { 25 f 3 ( i ) ; 26 } 27 } 28 29 } 30 31 i n t main ( ) { 32 r u n _ t e s t ( 3 ) ; 33 r e t u r n 1 ; 34 }

Figur A.1: Exempelprogram

A.4.1

Litteraturstudie om mjukvaruvisualiseringsverktyg

Källor har hittats via IEEE Xplore och Google Scholar där relevanta söktermer är: • Call graph

• Software Control Flow Graph • Software visualization • Program visualization • Software graph analysis • Software metrics • Code comprehension

Urvalet av källor i litteraturstudien har skett genom att använda källor som blivit citerade av andra. För att verifiera att källor blivit citerade användes Scopus citeringsdatabas.

A.5. Resultat

A.4.2

Generering av grafer och egenskaper

BPSA sparar båda formerna av analyser till olika filer. Genom att läsa in sparade analyser av exempelprogrammet i figur A.1 skapas tre olika grafer.

Genom att använda trädet från trace-analysatorn i BPSA skapas en anropsgraf över en körning av programmet. Från anropsgrafen bestäms maxdjupet. Genom att använda trädet från disassembly-analysatorn i BPSA skapas ett flödesschema över programmet. Från flödes- schemat räknas cyklomatisk komplexitet ut i varje funktion. Genom att kombinera träden skapas en graf med alla vägar programmet kan ta och de vägar som exekverats under kör- ningen från trace-parsern markeras. De genererade graferna visualiseras med hjälp av Grap- hviz och sparas som vektorgrafik då de kan bli stora.

A.5

Resultat

T. J. McCabe föreslår i [31] cyklomatisk komplexitet som ett mått på komplexitet hos funktio- ner och används i [34]. Cyklomatisk komplexitet räknas ut från flödesschemat av en funktion beskrivet i A.3.5.

B. G. Ryder föreslår anropsgrafer i [32] som ett verktyg för att analysera mjukvara och används i studierna [33, 35]. I samma studier används klusterkoefficienten och maxdjup som mätvärden hos anropsgrafer.

Utifrån litteraturstudien bedömdes flödesschema och anropsgraf som relevanta grafer att generera. Där cyklomatisk komplexitet, klusterkoefficient och maxdjup bedömdes som rele- vanta mätvärden.

A.5.1

Generering av grafer

Då BPSA inte kan i det allmänna fallet veta vilken adress som står på räkneregistret kan inte flödesscheman genererade från BPSA visa vägar där räkneregistret har använts. På grund av det kan det vara mer relevant att endast använda flödesschemat på funktionsnivå för att räkna cyklomatisk komplexitet.

Genom att kombinera trädet från körningsloggen med trädet genererat från den disas- semblerade filen går det att se vilka vägar som programmet inte har tagit. I figur A.2 visas ett kodträd där exekverade vägar är markerade med grönt och vägar som inte körts är markera- de med rött.

En dynamisk anropsgraf i exempelkoden ser ut som i figur A.3. Maxdjupet hos anrops- grafen med run_test som rotnod blir 2.

Ett flödesdiagram över run_test funktionen ser ut som i figur A.4. Den cyklomatiska komplexiteten räknas ut av V(G) = v+1 i grafen finns det 5 noder med fler än 1 bågar, den cyklomatiska komplexiteten blir då V(G) =5+1 =6. Cyklomatiska komplexiteten för samtliga funktioner finns i tabell A.2.

Funktion Komplexitet

f1 1

Related documents