Jaco Peeman en Casper de Lange November 2002 ABSTRACT... 2 INDEX... 2



Vergelijkbare documenten
Rev**** Model Aanpassingen

Analyse op.net software

Kleine cursus PHP5. Auteur: Raymond Moesker

Datatypes Een datatype is de sort van van een waarde van een variabele, veel gebruikte datatypes zijn: String, int, Bool, char en double.

XML Web Services of.net Remoting? W ANNEER GEBRUIK JE WELKE TECHNOLOGIE VOOR DE AANROEP VAN REMOTE SERVICES

Programmeren in Java 3

Tentamen Object Georiënteerd Programmeren TI oktober 2014, Afdeling SCT, Faculteit EWI, TU Delft

Universiteit van Amsterdam FNWI. Voorbeeld van tussentoets Inleiding programmeren

Datastructuren Werkcollege Intro

Zelftest Programmeren in Java

Het.NET framework in vogelvlucht

Hoofdstuk 1: Inleiding. Hoofdstuk 2: Klassen en objecten Datahiding: afschermen van implementatiedetails. Naar de buitenwereld toe enkel interfaces.

Modeleren. Modelleren. Together UML. Waarvan maken we een model? overzicht les 14 t/m 18. ControlCenter 6.2

Tentamen Object Georiënteerd Programmeren TI januari 2013, Afdeling SCT, Faculteit EWI, TU Delft

Zelftest Java concepten

Informatica. Objectgeörienteerd leren programmeren. Van de theorie met BlueJ tot een spelletje met Greenfoot... Bert Van den Abbeele

Om de libraries te kunnen gebruiken, moet de programmeur (een deel van) zijn programma in C/C++ schrijven.

Inleiding C++ Coding Conventions

DOMjudge teamhandleiding

Zelftest Inleiding Programmeren

Uitwerking Aanvullend tentamen Imperatief programmeren Woensdag 24 december 2014, uur

Een overzicht van het.net platform

icafe Project Joeri Verdeyen Stefaan De Spiegeleer Ben Naim Tanfous

4 ASP.NET MVC. 4.1 Controllers

Vraag 1. Vraag 1a TERUGKOPPELING PROEFTENTAMEN. Software architecture

Visual Basic.NET. Visual Basic.NET. M. den Besten 0.3 VB. NET

ArcGIS Mobile ADF. Smart Client Applicaties voor ArcGIS Server Eva Dienske, Wim Ligtendag

Een gelinkte lijst in C#

Object Oriented Programming

Modelleren en Programmeren

Verder zijn er de nodige websites waarbij voorbeelden van objectgeoriënteerd PHP (of Objec Oriented PHP, OO PHP) te vinden zijn.

UBC op Microsoft Windows 64-bits

Dynamische webapplicaties in Java

Zelftest Java EE Architectuur

Objectgeorïenteerd werken is gebaseerd op de objecten die door het systeem gemanipuleerd worden.

NHibernate als ORM oplossing

Programmeren in C# Interfaces. Hoofdstuk 23

Versturen van vanuit een Delphi VCL toepassing

Modelleren en Programmeren

Zelftest Informatica-terminologie

Programming Content Management Server 2002

Noties Informatica. In java fungeren objecten als een model voor de elementen waarin een probleem kan worden opgesplitst

Project Software Engineering XML parser: Parsen van een xml CD catalogus

Derde deeltentamen Imperatief programmeren - versie 1 Vrijdag 7 november 2014, uur

Informatica. Deel II: les 1. Java versus Python. Jan Lemeire Informatica deel II februari mei Parallel Systems: Introduction

OBJECT SPAGHETTI : PATTERNS BIEDEN UITKOMST? Wat is het probleem nou eigenlijk? public class CoffeeDrinker { private CoffeeProducer mycoffeeproducer;

Technisch Ontwerp W e b s i t e W O S I

Introductie in C++ Jan van Rijn. September 2013

Centrale begrippen hoofdstuk 3. Waarom multiprogramming? Vandaag. processen proces state: running, ready, blocked,... Vragen??

Inhoudsopgave. Hoofdstuk 1.RMI...2

DrICTVoip.dll v 2.1 Informatie en handleiding

Knowledgeable Referenceable Personable Accountable Scalable

Programmeren in Java 3

1 Inleiding probleembeschrijving

Enterprise Connectivity. Marnix van Bo. TU Delft Elek Software Architect 20 jaar ervarin ontwikkeling

Tentamen Imperatief en Object-georiënteerd programmeren in Java voor CKI

Programmeren in Java 3

Voor de database wordt een Access 2000 bestand gebruikt, met voorlopig 1 tabel:

Dynamiek met VO-Script

Teamhandleiding DOMjudge (versie 2.2.0muKP) 31 mei 2008

Vakgroep CW KAHO Sint-Lieven

IMP Uitwerking week 13


Uitwerking Tweede deeltentamen Imperatief programmeren - versie 1 Vrijdag 21 oktober 2016, uur

Uitgebreid eindwerkvoorstel Lokaliseren van personen en objecten met behulp van camera s

Modelleren & Programmeren. Jeroen Fokker

Datastructuren en algoritmen

Ontwerp van Informatiesystemen

Modulewijzer Tirdat01

Een stoomcursus door Edgar de Graaf, november 2006

Mijn eerste ADO.NET applicatie

Een.NET-besturingssysteemtoolkit. Discovering Cosmos. Sijmen J. Mulder

Uitwerkingen Tweede deeltentamen Imperatief programmeren Vrijdag 15 oktober 2010, uur

Programmeren in C++ Efficiënte zoekfunctie in een boek

Modulewijzer tirprog02/infprg01, programmeren in Java 2

Standard Parts Installatie Solid Edge ST3

Session Beans.

Les 11: systeemarchitectuur virtuele machines

VB Magazine Online /08 1 / 6

Modelleren en Programmeren

SYNTRA-WEST. Initiatiecursus JAVA. Deel

Zope. Een technische introductie. Martijn Pieters Antraciet BV V september 1999

Aan het eind van deze lesbrief wordt uitgelegd wat het nut van OOP is en vind je een aantal oefenopdrachten.

DIAGNOSTISCHE TOETS Softwaresystemen UITWERKING

ASRemote WebService. Via deze webservice kunt u:

Microsoft.NET: De toekomst is dichterbij dan u denkt

Derde deeltentamen Imperatief programmeren - versie 1 Vrijdag 6 november 2015, uur

Datastructuren: stapels, rijen en binaire bomen

Stacks and queues. Introductie 45. Leerkern 45. Terugkoppeling 49. Uitwerking van de opgaven 49

Nederlandse samenvatting (Dutch summary)

Vereiste kennis. 1 Java-editor. 2 Het compileren van een programma

eerste voorbeelden in Java

Overerving & Polymorfisme

INLEIDING... 1 AFSPRAKEN... 2 INHOUDSOPGAVE...

Programmeren: Visual Basic

JSF webapplicatie performance

Tentamen Objectgeorienteerd Programmeren TI februari Afdeling ST Faculteit EWI TU Delft

Klassen & objecten, overerving, abstracte klassen, debuggen, interfaces, formulieren, polymorfie, statische methoden, event-handlers

Inhoud Inhoud. Over dit boek 7. 1 Eclipse IDE (Integrated Development Environment) 9. 2 Functionele specificatie 13

Programmeren. Cursus Python

Transcriptie:

Abstract Dit artikel is geschreven in het kader van het afstuderen van Jaco Peeman en Casper de Lange, studenten aan de universiteit van Utrecht. Het onderzoek is gedaan in opdracht van Gert Florijn van het SERC. We behandelen de mogelijkheden om RevJava, een Java-code analyser, uit te breiden met: Analyse op Microsoft.net Extra type-analyse Alias analyse Tevens hebben we gekeken naar enkele andere oplossingen voor code-analyse, te weten SOUL en metacompilatie. Index Jaco Peeman en Casper de Lange November 2002 ABSTRACT... 2 INDEX... 2 1. HET DOTNET PLATFORM... 4 INLEIDING... 4 FRAMEWORK... 4 Common Language Runtime (CLR)... 5 Intermediate Language (IL)... 5 Just In Time (JIT) compiler... 5 Common Type System... 6 Common Language Specification... 6 Value Types versus Reference Types... 6 Pointers... 7 XML Web Services... 8 Java User Migration Path (JUMP) en J#... 8 WAT IS ER AL GEDAAN OP DIT GEBIED... 9 FXCop... 9 Total.NET Analyzer... 9 MetaPuck... 9.NET Reflector 2.4... 9 NOTE... 9 HET.NET METAMODEL... 10 VOORBEELD IL FILE... 12 GEVOLGEN VOOR REVJAVA... 13 2. HET FAMIX MODEL... 14 3. ALIAS ANALYSE... 16 WAT IS ALIAS ANALYSE... 16 RELEVANTIE TEN OPZICHTE VAN REVJAVA... 16 WAT IS ER AL GEDAAN OP DIT GEBIED... 18 Flexible alias encapsulation... 18 SCALE... 19 Demand Driven Pointer Analysis [2]... 19 Reference-Set Representation [5]... 19 GEVOLGEN VOOR REVJAVA... 20 Haalbaarheid... 20 4. TYPE ANALYSE... 21 WAT IS ER AL GEDAAN... 22 GEVOLGEN VOOR REVJAVA... 23 Toevoegen van nullpointer detectie... 23 2

Toevoegen van typebepaling van types in een Vector... 23 Toevoegen van overflow analyse... 24 Toevoegen van analyse van concurrente programma s... 24 HAALBAARHEID... 24 Toevoegen van nullpointer detectie... 24 Toevoegen van type analyse in een Vector... 24 Toevoegen van overflow analyse... 25 Toevoegen van analyse van concurrente programma s... 25 5. DESIGN INFORMATIE UIT DE IMPLEMENTATIE AFLEIDEN... 26 SOUL (SMALLTALK OPEN UNIFICATION LANGUAGE)... 26 Voorbeeld SOUL: Composite Patterns... 26 REVJAVA EN DESIGN INFORMATIE... 28 6. META COMPILATIE... 29 METAL... 29 GEVOLGEN VOOR REVJAVA... 29 HAALBAARHEID... 30 7. REFERENTIES... 31.NET PLATFORM... 31 FAMIX... 31 ALIAS ANALYSE... 31 TYPE ANALYSE... 31 SOUL... 32 META COMPILATIE... 32 8. APPENDIX... 33 AFSTUDEEROPDRACHT SERC... 34 TEMPLATE VOOR ONDERZOEK... 36 AFSTUDEERPLANNING... 37 AFSTUDEERPLANNING 2... 38 VOORTGANGS GESPREK... 38 3

1. Het dotnet platform Inleiding Microsoft Dotnet is een raamwerk waarmee men beter, efficiënter en gemakkelijker informatievoorzieningen binnen een organisatie kan realiseren. Met behulp van dotnetsoftware is bijvoorbeeld communicatie tussen applicaties efficiënter en veiliger dan wat we op dit moment als standaard hebben. Het is in wezen een evolutie naar betere softwareontwikkeling technologie. Microsoft dotnet bestaat op dit moment uit de volgende drie onderdelen. dotnet Framework: Het framework is de basis voor alle software die gebruik maakt van dotnet functionaliteit. Voor de gebruiker is het een software programma dat wordt geïnstalleerd en eigenlijk alles achter de schermen regelt. dotnet Servers: Dit zijn server produkten (vooral van Microsoft) die op verschillende gebieden voor dotnet geoptimaliseerd zijn. Zoals SQL Server 2000. dotnet Web Services: De web services zijn internet diensten die voor client applicaties aanroepbaar zijn. Framework Het dotnet framework vormt de infrastructuur voor het dotnet platform. Het zorgt ervoor dat het bouwen van Web Services transparant wordt voor ontwikkelaars. Dit framework beschikt over een applicatiemodel en de technologieën die het ontwikkelen en beheren van Web Services vereenvoudigen. Er zijn drie hoofdonderdelen waar het framework uit bestaat: Common Language Runtime (CLR): CLR beheert de eisen van het runnen van code die in een willekeurige programmeertaal geschreven is. Het zorgt ervoor dat er geen speciale interfaces, zoals IUnknown en Idispatch, geïmplementeerd hoeven te worden. Ontwikkelaars implementeren hun classes eenvoudig in de door hen gewenste programmeertaal. Unified Class Libraries: De classes van het.net Framework vormen een hiërarchische reeks class libraries die ontwikkelaars kunnen gebruiken vanuit de talen waarmee ze al vertrouwd zijn. ASP.NET: ASP.NET beschikt over een low-level programmeermodel en over high-level programmeermodellen voor het bouwen van webapplicaties (ook wel Web Forms genoemd). Het is vanuit ASP.Net heel eenvoudig om een Web Service te definiëren. 4

Common Language Runtime (CLR) De CLR is de abstractielaag tussen het besturingssysteem en de.net applicatie die wordt uitgevoerd, en is daarmee een erg essentieel element binnen het.net framework. De CLR omvat een aantal verschillende componenten, waaronder de Intermediate Language (IL), het Common Type System (CTS) en een Virtual Execution System (VES) voor IL. De CLR heeft de volgende taken: Het managen van geheugen Het beheren (opstarten, killen) van threads en processen Zorg dragen voor beveiliging Afhandelen afhankelijkheden tussen applicaties en assemblies Voor ieder besturingssysteem is er een aparte CLR. Wanneer men bijvoorbeeld.net op een ander platform dan Windows wil draaien, zal men zelf voor een CLR voor dat platform moeten zorgen. Intermediate Language (IL) De IL compilers van de verschillende.net talen (o.a.: C#, Visual Basic) compileren de sourcecode allen naar IL in plaats van naar machinecode. Dit maakt het gebruik van een runtime nodig, in het geval van.net is dit dus de CLR. Wanneer een applicatie wordt opgestart, wordt de IL met behulp van de Just In Time (JIT) compiler gecompileerd naar machinecode. Binnen de CLR is het VES verantwoordelijk voor de executie van de code en de JIT compilatie. Om taal onafhankelijk te kunnen zijn is de IL object georiënteerd gedefinieerd, en wordt er gebruik gemaakt van meta-data welke bij gecompileerde sourcecode opgeslagen is. Een blok gecompileerde sourcecode met meta-data noemt men ook wel een assembly. Een programmeur kan nu zonder de sourcecode te hebben van zo n assembly gebruik maken van de assembly, ook als hij in een andere (naar IL te compileren) programmeertaal schrijft dan waarin de assembly oorspronkelijk geschreven was. De IL is sterk getypeerd, omdat alle talen dezelfde datatypen moeten gebruiken. De typering zit in het Common Type System (CTS) en de datastructuren hierin zijn in een hiërarchische object-structuur opgebouwd. Just In Time (JIT) compiler De JIT zorgt voor multi-platform inzet van.net-applicaties. Aangezien verschillende platforms verschillende machinecodes kunnen hebben (b.v. Unix en Windows) maakt de JIT compiler de specifieke machinecode voor het platform waarop de CLR draait. Ondanks dat de IL gecompileerd wordt wanneer deze nodig is, is een.net applicatie niet (of niet veel) langzamer dan een normale applicatie die in de Windows omgeving draait. De eerste reden is dat de JIT compiler een machinecode genereert welke optimaal is voor de processor die op dat moment gebruikt wordt. Dit is bij niet.net applicaties moeilijk te doen omdat dan per processor een aparte versie van de applicatie geschreven moet worden. Ten tweede bestaat een.net applicatie uit meerdere assemblies, welke pas worden geladen wanneer zij nodig zijn. Bij de start van het programma worden slechts een aantal assemblies gecompileerd, de rest pas wanneer zij nodig blijken te zijn. Gecompileerde assemblies worden in een cache geladen zodat zij bij een volgende aanroep niet weer opnieuw gecompileerd hoeven te worden maar vanuit de cache geladen kunnen worden. 5

Figuur 1.1: een schematische weergave van sourcecode tot de executie van een applicatie. Het grijze vlak is de CLR. Common Type System Het Common Type System is een belangrijk component voor inter-operabiliteit binnen.net. Voor inter-operabiliteit is het van belang dat verschillende.net talen dezelfde types gebruiken, het CTS definieert types en regels in het gebruik hiervan. De types staan in een hiërarchische structuur gedefinieerd binnen het Common Type System. Door deze types te gebruiken kunnen programmeurs assemblies die in een andere taal geprogrammeerd zijn gebruiken. Common Language Specification Om interactie tussen objecten in verschillende talen mogelijk te maken moeten objecten alleen de gezamenlijke features blootgeven. Hiervoor is een verzameling taal features gedefinieerd: de Common Language Specification (CLS), welke de basis taal features bezit die nodig zijn voor veel applicaties. Het is dus een subset van het Common Type System. Value Types versus Reference Types Het Common Type System kent 2 soorten types: value types en reference types. Value types bevatten de waarde van het desbetreffende type (int, boolean, double e.d.), terwijl referentie types een referentie of pointer naar het werkelijke object zijn.. In C# is het mogelijk value types te converteren naar een referentie type, het zogenaamde boxen. Het unboxen geschiedt met behulp van een cast. 6

Pointers Pointers zijn speciale variabelen. Er zijn 3 soorten die ondersteund worden in de runtime: Managed pointers: dit is een nieuw type pointer die beschikbaar is voor door dotnet gemanaegde applicaties. Het zijn referenties naar een gemanaged stuk geheugen. Alleen deze pointers zijn geschikt voor de Common Language Specification. Unmanaged pointers: dit is de traditionele C++ pointer. Een unmanaged pointer wordt niet ondersteund door de CLS, dus mag niet gebruikt worden. Unmanaged function pointers: dit is ook een C++ pointer die refereert aan het adres van een functie. Een unmanaged function pointer wordt niet ondersteund door de CLS, dus mag niet gebruikt worden. 7

XML Web Services XML Web Services zijn de fundamenten voor het gedistribueerde gebruik van applicaties over het internet. Het maakt vooral gebruik van bekende protocollen als HTTP, TCP-IP en XML. Microsoft s DotNet is een platform dat gebruikers in staat stelt deze services te schrijven, gebruiken en beheren. Er zijn zeer veel verschillende definities van XML Web Services. Deze hebben echter bijna allemaal het volgende gemeen: XML Web Services levert bruikbare functionaliteit aan gebruikers van het internet via een standaard protocol. In veel gevallen is het gebruikte protocol SOAP (Simple Object Access Protocol). Andere bekende protocollen zijn CORBA en Java/RMI. XML Web services leveren een duidelijke beschrijving van de interfaces die beschikbaar zijn voor client applicaties. Deze beschrijving is meestal verkrijgbaar via een Web Services Description Language (WSDL) document. XML Web services zijn geregistreerd zodat potentiële gebruikers hen eenvoudig kunnen vinden. Deze naming service is Universal Discovery Description and Integration (UDDI) genoemd. Java User Migration Path (JUMP) en J# Het.net platform ondersteunt geen Java applicaties. Microsoft had wel een manier ontwikkeld om via een omweg toch Java in.net te ondersteunen. Dit kon via Java User Migration Path (JUMP). JUMP is een verzameling technologieën en diensten die het mogelijk maakt om Java files dusdanig te migreren dat ze in het.net framework geïntegreerd kunnen worden. JUMP levert een tool dat Java sourcecode migreert naar C#. J# is een upgrade van Visual J++ 6.0, zodat dit geschikt wordt voor.net. Met J# worden Java programmeurs in staat gesteld software voor.net te ontwikkelen in Java. Met J# moet het mogelijk zijn gemakkelijk webservices te ontwikkelen en inter-operabiliteit te bieden aan Java met andere programmeertalen via de IL van.net. J# levert ondersteuning voor de meeste class libraries van JDK 1.1.4, en de class libraries van Visual J++ 6.0. Het heeft een aantal features: Libraries voor JDK 1.1.4, behalve voor JNI,RMI en Applets..Net heeft zijn eigen remoteservices. Voor Applets zal in de toekomst een oplossing gevonden moeten worden. Ondersteuning om Visual J++ 6.0 projecten te importeren, te compileren en te debuggen. Een Java (versie 1.1.4) to IL compiler, welke Java source files compileert naar IL. Een Java (versie 1.1.4) class to IL compiler, welke libraries in class files compileert naar assemblies zodat deze conform IL zijn en kunnen runnen in de CLR. J# is niet bedoeld om applicaties mee te schrijven welke in een Java Virtual Machine (JVM) moeten runnen, dit wordt niet ondersteund. J# is free of charge te downloaden op: - http://msdn.microsoft.com/vjsharp/downloads/howtoget.asp 8

Wat is er al gedaan op dit gebied We hebben een aantal tools gevonden die een analyse op.net programma s doet. Aangezien.net nog vrij nieuw is hebben we geen parsers voor.il files gevonden, maar er waren wel aanwijzingen die aangaven dat deze ontwikkeld werden. Hieronder staan een aantal door ons bekeken programma s. FXCop FxCop is een tool dat code analyse uitvoert op dotnet applicaties met betrekkingen tot de design guidelines van het dotnet framework. Het gebruikt hierbij reflectie, MSIL parsing en analyse van de callgraph. Er worden meer dan 175 kritieken bekeken zoals: naming conventions, library design, localization, veiligheid, en performance. Zie ook: http://www.gotdotnet.com/team/libraries/ Total.NET Analyzer Total.NET Analyzer is een plug-in voor Visual Studio.NET. Het voert gedetailleerde analyse uit op C# en VB.NET code (dus lang niet alle dotnet talen). Het bekijkt ongeveer 150 kritieken die gerelateerd zijn aan errors, ongebruikte code, performance, naming conventions en standards. Zie ook: http://www.fmsinc.com/dotnet/analyzer/faq.asp#whatistotal MetaPuck MetaPuck bekijkt de meta-data in de CLR en geeft deze weer in een tree, zodat de meta-data overzichtelijk gepresenteerd kan worden. Zie ook: http://www.downlinx.com/proghtml/365/36582.htm.net Reflector 2.4 Op http://www.aisto.com/roeder/dotnet/ staan een aantal tools voor.net, waaronder een IL reader en een reflector voor.net. Met de reflector kan men classes bekijken in componenten en assemblies. Tevens kunnen assembly dependency trees en inheritance issues bekeken worden. Zie ook: http://www.aisto.com/roeder/dotnet/ NOTE Aangezien voor installatie van de.net SDK minimaal MS Windows 2000 en MS Internet Information Server benodigd waren konden we de bovengenoemde tools niet of nauwelijks testen. 9

Het.net metamodel Wanneer RevJava Microsoft.net wil kunnen inlezen zal de informatie uit IL files in het metamodel van RevJava ingelezen moeten worden. Deze sectie bekijkt of dit mogelijk is en wat voor aanpassingen er aan het bestaande metamodel van RevJava zullen moeten plaatsvinden om dat mogelijk te maken. Een.net programma kan uit verschillende assemblies bestaan en een assembly uit verschillende modules. De CLR kan runtime assemblies vinden met behulp van ingebouwde algoritmes. De globale opbouw van een assembly ziet er als volgt uit: Single file assembly Multiple file assembly Een assembly is enigszins vergelijkbaar met een.jar file van Java. De metadata is voornamelijk nodig om andere assemblies op een gemakkelijke manier gebruik te kunnen laten maken van een assembly. Een multiple file assembly moet aangemaakt worden als men modules geschreven in verschillende talen wil combineren, of als het programma typen bevat welke bijna nooit nodig zijn en alleen af en toe geladen hoeven worden. In het manifest staat informatie over de assembly, zoals bijvoorbeeld welke files er tot een assembly behoren. Informatie uit die files kan aan de assembly worden opgevraagd (welke types er in de assembly zitten, welke classes geëxporteerd mogen worden) maar is in de classes zelf gedefinieerd. Een uitgebreider model van een assembly staat op de volgende pagina. 10

1 Assembly manifest Type metadata Ass. dependencies 1 1..* 1..* Metadata element Assembly 1..* 1..* Module 1 * * Resource Image Static ass. Dynamic ass. X509 Certificate 1 0..1 1..* Type code Text Private Public (shared) 1 IL Machine code Global ass. cache 1 * Interface 1 * 1 Namespace 1 * Class * Method Field Property Event Nested type Parameter Figuur 1.2 Het metamodel van de MSIL is object georiënteerd opgebouwd en geschikt voor alle talen waarin.net geprogrammeerd kan worden. Verder is het zo dat alle datatypen in.net objecten zijn, deze zijn in een hiërarchische object structuur gedefinieerd. Er zal gekeken moeten worden hoe RevJava deze types zal moeten afhandelen. De complete lijst van ingebouwde types is te vinden op: http://msdn.microsoft.com/library/en-us/cpguide/html/cpconthenetframeworkclasslibrary.asp Wanneer we.net gaan parsen naar het metamodel van RevJava zullen we goed na moeten denken hoe we dit precies gaan aanpakken. Het zou het makkelijkst zijn als er al een bestaande parser voor IL zou zijn, die wij zouden kunnen gebruiken. Anders zullen we een parser voor de gehele.net grammatica moeten schrijven, met de mogelijkheid aan te geven (d.m.v. flags) wat er wel en niet geparsed moet worden. Hierop moeten we dan het metamodel van RevJava aanpassen. Er zal gekeken moeten worden hoe pointers moeten worden toegevoegd in het metamodel van RevJava, en hoe namespaces afgehandeld gaan worden. Waarschijnlijk zullen we het metamodel van RevJava moeten uitbreiden met een namespace object. In het model zullen er bij objecten extra flags gedefinieerd moeten worden welke gebruikt worden door.net bij verschillende objecten (classes, methodes) maar niet door Java. 11

Voorbeeld il file We zullen een klein voorbeeld van een il file bekijken. We schrijven een C# implementatie van Hello World. using System; class App{ public static void Main(){ Console.WriteLine("Hello World!"); Om hier een assembly van te maken gebruiken we ilasm en ildasm om de.il file en een.exe file te creëren. Ildasm.exe parsed elke.exe of.dll assembly en geeft de informatie op een overzichtelijke manier weer. Het laat meer zien dan alleen de MSIL code, het geeft tevens namespaces en types weer. Tevens kun je de manifest informatie van een assembly opvragen. Met behulp van ildasm.exe kun je snel informatie opvragen over assemblies van Microsoft, iemand anders of jezelf. Hieronder staat de il file van assembly HelloWorld.exe. // De assembly HelloWorld maakt gebruik vand de volgende assemblies:.assembly extern mscorlib{.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ).ver 1:0:3300:0 // Algemene info over de assembly.assembly HelloWorld{.hash algorithm 0x00008004.ver 0:0:0:0.module HelloWorld.exe.imagebase 0x00400000.subsystem 0x00000003.file alignment 512.corflags 0x00000001 // Class structuur informatie.class private auto ansi beforefieldinit App extends [mscorlib]system.object{ // Globale variabelen en methoden.class private auto ansi beforefieldinit App extends [mscorlib]system.object{.method public hidebysig static void Main() cil managed {.entrypoint.maxstack 1 IL_0000: ldstr "Hello World!" IL_0005: call void [mscorlib]system.console::writeline(string) IL_000a: ret 12

.method public hidebysig specialname rtspecialname instance void.ctor() cil managed {.maxstack 1 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]system.object::.ctor() IL_0006: ret Gevolgen voor RevJava Reader: De parser zal aangepast moeten worden aan de IL files. Tot nu toe zijn we nog geen parsers tegengekomen. Tevens zal het meta-model anders zijn dus zal de uitvoer van de reader ook anders zijn (o.a. pointers zitten wel in dotnet en niet in RevJava). Model: Zie pagina 11 voor een vergelijking van het RevJava meta-model met het dotnet meta-model. Critics: De kritieken zullen aangepast moeten worden aan het nieuwe model en aan de architectuur van RevJava. Performance: De performance van RevJava op.net zal waarschijnlijk niet heel veel afwijken van RevJava op.net, maar dit is moeilijk te voorspellen aangezien er nog geen parser is. Haalbaarheid Het aanpassen van RevJava (wellicht moet ook de naam gerefactored worden) aan dotnet lijkt haalbaar. Minimaal moet het model worden aangepast (b.v. assemblies toevoegen), zodat voor.net hetzelfde model opgebouwd kan worden als nu voor Java gebeurd. Wanneer er ook over de assemblies informatie weergeven moet worden, moet het model verder worden uitgebreid. Dit kan later altijd nog als opdracht worden gezien. 13

2. Het Famix Model Het Famix model is een manier om classes van een OO taal te ontleden. Het is ontworpen ongeveer tegelijk met het metamodel van RevJava, wat meer Java georiënteerd is opgezet. Het is interessant om een vergelijking te maken tussen de modellen, omdat wij de mogelijkheid onderzoeken.net in het model van RevJava in te voegen. Hieronder staat het FAMIX model: Figuur 2.1: het FAMIX model. Dit model bestaat uit vier entiteiten: Class, Method, Attribute en InheritanceDefinition. Verder hebben we Invocation en Access nodig. Een invocatie representeert een methode die een andere methode aanroept. Een access representeert een methode die een variabele aanroept. Hiermee zijn taken als afhankelijkheidsanalyse, metriek berekeningen en reengineering operaties mogelijk. Het basis meta-model staat in de volgende figuur: Figuur 2.2: Het complete FAMIX Meta Model. 14

Object, Property, Entity and Association zijn beschikbaar voor het definiëren van taal plug-ins. Hiervoor moet het data model uitbreid worden met taal specifieke entiteiten en eigenschappen. Sommige tools willen ook hun eigen properties kunnen definiëren. Voor het specificeren van taal plug-ins is het toegestaan om taalspecifieke objecten te definiëren. Tevens is het toegestaan om taalspecifieke attributen aan Objecten toe te voegen. Hieronder worden de diverse onderdelen wat uitgebreider besproken: Object: object is de alles overkoepelende klasse. Het bevat de volgende attributen: sourceanchor (locatie van de start en eind index in de source file) en comments (handmatig ingevoerde informatie). Object is vergelijkbaar met JElement in het object model van RevJava. Property: deze klasse representeert eigenschappen voor objecten. Vergelijkbaar met Jprops in RevJava. Entity: een entiteit heeft een eigen naam en een unieke naam. Dit omdat bijvoorbeeld methoden in verschillende klassen dezelfde naam mogen hebben. Vergelijkbaar met JIdElement in RevJava. Model: een model bevat informatie over het specifieke systeem dat gemodelleerd wordt. Er mag slechts één instantie van Model bestaan. Het bevat o.a. de volgende attributen: sourcelanguage (de gebruikte programmeertaal), parsedsystemname (naam van het systeem waar informatie uit gehaald is) en publishername (de naam van de persoon die de informatie gegenereerd heeft). Package: deze klasse is vergelijkbaar met JPackage in Revjava. Waarschijnlijk is Jsystem in Revjava de overkoepelende package in FAMIX. Class: deze klasse is vergelijkbaar met JClass in Revjava. Er is geen definitie voor Jinterface, maar de Java plug-in voegt een extra attribuut isinterface toe. Behavioural: deze entiteiten definiëren het gedrag van de klasse, zoals methoden in java. Method: Is vergelijkbaar met JMethod in RevJava. Function: Is niet van belang. Structural: alle mogelijke variabele definities zijn subklassen van Structural. Vergelijk Jfield in RevJava. Attribute: attributen zijn globale variabelen van een klasse. Vergelijkbaar met JField in RevJava. ImplicitVar: impliciete variabelen representeren de definitie van context afhankelijke referenties aan een geheugen adres. in Java zijn this, super en class impliciete variabelen. GlobalVar: niet van toepassing. LocalVar: locale variabelen zijn de variabelen in een methode. Vergelijkbaar met JVariable in RevJava. FormalPar: een formele parameter representeert welke parameters een methode verwacht. Inheritance: deze klasse representeert de definitie van sub- en superklassen. De Java plug-in ondersteunt single inheritance. Dit zit impliciet al in Jtype. Access: het aanroepen van een globale of locale variabele. Dit is JOpFieldRef in RevJava. Invocation: het aanroepen van een methode. Dit is JOpCall in RevJava. Argument: een Argument representeert het doorgeven van een parameter. Inner classes zijn niet ondersteund in FAMIX. 15

3. Alias Analyse Wat is Alias Analyse Wat is alias analyse? Dit wordt verduidelijkt aan de hand van een kort voorbeeld. In figuur 1a is te zien dat de klasse Aholder instanties van de klasse A beheert. Dit houdt in dat alle klassen die een instantie van de klasse A willen gebruiken alleen via Aholder bij A zouden moeten kunnen komen. Wanneer er echter een klasse B ook een pointer heeft naar het door Aholder beheerde a_object spreken we van aliassen. Het private of protected maken van een object is al iets beter echter hier kan via een get of set methode ook een pointer naar het desbetreffende object verkregen worden. Class Aholder Class A private A a_object; Class B Figuur 3.1a: UML van beheer klasse Aholder van A en een klasse B die een Aholder object bezit. Aholder_object _ a_object b_object Figuur 3.1b: Aliassen van a_object. Het gevolg van aliassen is onder andere: Het object georiënteerde programma wordt onoverzichtelijk voor de programmeur. Het aanpassen van een dergelijk programma wordt lastiger. Aliassen maken de programmatuur gevoelig voor verandering en hebben vaak bugs tot gevolg. Tevens wordt de analyse van de applicatie lastiger. Relevantie ten opzichte van RevJava RevJava is erop gericht om de gebruiker op mogelijke verbeteringen in de Java code te wijzen. Het toevoegen van alias analyse zou tot een nog beter en completer advies kunnen leiden. Performance is echter ook erg belangrijk, dus het is wel belangrijk dat het huidige meta-model van RevJava zoveel mogelijk gebruikt kan worden, eventueel na enkele gerichte aanpassingen. De vraag is dan ook of alias analyse toegevoegd kan worden zonder dat er al te veel extra datastructuren geconstrueerd moeten worden. Liefst gebruiken we natuurlijk alleen het meta-model. 16

Waarschijnlijk is het voor een gebruiker interessant om per object de alias analyse te kunnen doen. Dat betekent dus dat er een extra feature toe gevoegd moet worden die alleen alias analyse doet en verder niets met het uitvoeren van de andere kritieken te maken heeft. 17

Wat is er al gedaan op dit gebied Er is nog weinig geïmplementeerd op het gebied van Alias Analyse in Java applicaties. Wel is er het één en ander gedaan in C en C++. Flexible alias encapsulation Paper [1] behandelt een methode van alias analyse genaamd flexible alias encapsulation. Deze methode gaat uit van het feit dat aanwezigheid van aliassen niet het probleem is. De onverwachte veranderingen aan de staat van een object leveren de problemen op. Dus richt flexible alias encapsulation zich niet op het voorkomen van aliassen, maar op het vermijden van het veranderen van kritieke delen van objecten waarvan meerder aliassen bestaan. Om het te verduidelijken wordt een voorbeeld besproken. De hashtable a in figuur 3 bestaat uit een int size en een array contents. Deze array is private voor de hashtable. Object d mag dus wel een object uit de array aanspreken en aanpassen echter niet het array object zelf. Dit suggereert een nieuwe manier van aanpak. Niet langer wordt het bestaan van meerdere aliassen verboden, maar de zichtbaarheid van veranderingen voor objecten. Aliassen worden getolereerd zolang veranderingen van gealiaste objecten onzichtbaar blijft. Om dit te realiseren introduceert men de alias-protected container. Deze container heeft een private representation (niet beschikbaar van buitenaf) en public arguments (voor elk object beschikbaar). Deze methode legt echter heel veel verantwoordelijkheid bij de programmeur, en dat is precies wat we niet willen. figuur 3.3: Hashtable 18

SCALE Scale [3] is een c-compiler geschreven in Java die tijdens het compileren alias analyse uitvoert op de software. Het werkt volgens het algoritme van Steengaard [4]: Geef elke variabele in het programma een unieke typereferentie variabele. Zet elke typereferentie variabele initieel op null. Elk statement wordt precies 1 keer uitgevoerd. Type variabelen worden samengevoegd als dat nodig is. Na afloop is het dus mogelijk om te checken of er meerdere variabelen naar dezelfde typereferentie variabele verwijzen. Dit uiteraard niet waterdicht in een object georiënteerde taal, waar het nooit voor zal komen dat statements slechts één keer uitgevoerd worden. De complexiteit van dit algoritme is O(n) zowel qua tijd als ruimte. Het is onwaarschijnlijk dat dit algoritme echt interessante informatie oplevert voor object georiënteerde talen, het zal de voor de hand liggende aliassen waarschijnlijk wel detecteren, echter de echt interessante aliassen niet. Demand Driven Pointer Analysis [2] Dit algoritme richt zich op het zoveel mogelijk vermijden van ingewikkelde technieken en datastructuren. Het is ontworpen voor analyse van C en C++ programmatuur. Net als veel andere alias analyse algoritmes maakt het gebruik van zogenaamde points-to sets. Een points-to set bevat alle mogelijke verwijzingen van een variabele naar andere variabelen of waarden. Eerst worden alle points-to sets berekend. Op deze sets kunnen queries gedaan worden zoals: waarnaar zou variabele x kunnen verwijzen. Er is een verzameling deductie regels gedefinieerd die met behulp van de points-to sets kunnen bepalen waar een variabele naar verwijst. En daarmee kan weer bepaald worden naar welke geheugen plekken verwezen wordt. Het is echter geen volledig algoritme voor alias analye, en tevens wordt het getest op een supercomputer. Dus misschien dat het een startpunt kan zijn voor onderzoek, maar gezien de performance eisen van Revjava is het onwaarschijnlijk dat deze analyse op het gehele programma uitgevoerd kan worden. Misschien is het interessant om per object de aliassen te bekijken. Reference-Set Representation [5] De reference-set representation is gebaseerd op sets met referenties naar een object, de zogenaamde reference-sets. De referentie sets die meer dan 2 referenties bevatten, worden in een alias set verzameld. De referentie sets worden ingevuld met behulp van twee data structuren: de call graph, en de control flow graph. De call graph is een gerichte graaf die het volgende bevat: methoden (knopen), aanroepen van methoden (edges) en het startpunt (de main methode). Er is voor elke methode een control flow graph is een gerichte graaf die het volgende bevat: statements (knopen), alias set informatie tussen statements (edges), en een methode-entry en methode-exit knoop. Op deze datastructuren wordt een algoritme toegepast dat de alias informatie uitrekent. Dit algoritme voert een precies analyse uit, echter de performance is voor een volledige analyse ontoereikend. Dus zal er per object of verzameling objecten gekeken moeten worden. 19

Gevolgen voor RevJava Reader: momenteel leest de reader alleen informatie over de klasse waarvan het object een instantie is. Het moet mogelijk zijn om een points-to graph te maken van de informatie die uit de reader komt. Dit houdt in dat er bijgehouden moet worden naar welk object de pointer verwijst. Model: het model zal uitgebreid moeten worden met òf informatie over welke objecten andere objecten aanspreken òf informatie over welke objecten aangesproken worden door andere objecten. Critics: waarschijnlijk zal alias analyse een onafhankelijke feature worden. Het is te langzaam om tegelijk met de andere critics uitgevoerd te worden. Performance: het ziet ernaar uit dat de performance van RevJava opgeofferd zal worden wanneer alias analyse als standaard kritiek meegenomen wordt. Een optie is om deze analyse als een aparte feature aan te bieden, maar de reader zal extra informatie moeten leveren en zal dus ook langzamer worden. Haalbaarheid Performance was vooraf één van de belangrijkste items. Om alias analyse toe te kunnen voegen zal de reader veel extra werk moeten doen. Tevens moet via een flow analyse bekeken worden in hoeverre de variabelen later nog naar een ander object gaan verwijzen. Tevens kan tijdens het ontwerpen van het nieuwe meta-model de compatibiliteit met een model voor andere analyses meegenomen worden. 20

4. Type analyse Type analyse houdt in dat er uit Java class files type informatie wordt gehaald en dat deze informatie wordt gebruikt om met behulp van regels te checken of het programma aan bepaalde voorwaarden voldoet. We willen de mogelijkheden voor meer type analyse in RevJava doen, te denken valt aan dingen als: Nullpointer detectie: nullpointer exceptions zijn ernstige programmeer fouten welke door de compiler niet gedetecteerd worden. Bij een slechte exceptionafhandeling kan een nullpointer de applicatie geheel plat leggen. Class aclass { String s; aclass() { System.out.println( s.length() ); Figuur 4.1 In de figuur hier boven staat een voorbeeld van een nullpointer exception die niet afgevangen is. Typebepaling van objecten die in een Vector opgeslagen worden: het zou handig kunnen zijn om te weten wat voor types er in een Vector worden opgeslagen, zie onderstaande figuur: class Vector ps aclass = new Vector(); class Persoon public addp(persoon p) { ps.addelement(p); class Man class Vrouw Figuur 4.2: Wanneer zou blijken dat er in aclass.ps slechts Personen van type Man worden gestopt, zou in plaats van een Vector bijvoorbeeld ook een array gedefinieerd kunnen worden, of zou het bij lezen van een element uit de Vector een betere cast kunnen plaatsvinden. Overflow errors van bijvoorbeeld arrays: void amethod(int[] a) { int n = a.length; for(int i = 0; i <= n; i++) a[i]++; Figuur 4.3: De index i bereikt hier een waarde buiten het bereik van de array, die loopt van 0 n-1. Analyse van concurrente programma s: bijvoorbeeld deadlock detectie of te veel synchronisatie (dit kan de applicatie traag maken). 21

class A { synchronized f() { b.g(); synchronized g() { class B { synchronized f() { a.g(); synchronized g() { Figuur 4.4: In bovenstaande figuur is een mogelijke deadlock aangegeven. Wanneer twee threads A.f() en B.f() willen gebruiken locken ze beiden de classes, en creëren zo een deadlock. Het betreft hier zaken welke eigenlijk pas runtime aan het licht komen, de vraag is nu of RevJava deze al kan opsporen. Het gaat niet alleen over het opsporen van fouten in de code, maar ook over suggesties om de code te optimaliseren. Wat is er al gedaan Er is op dit gebied al wat onderzoek gedaan. Zeker op het gebied van nullpointer detectie en concurrente programma s zijn er voorbeelden van programma s die fouten in de binaire code opsporen. Enkele voorbeelden: Jlint Visual Threads ESC/Java De methodes die gebruikt worden voor de analyse zijn echter meestal niet nauwkeurig omschreven, tevens hadden alle programma s last van een foutmarge in de analyse. Op het gebied van types in een Vector hebben we niets kunnen vinden, over overflows was enige informatie beschikbaar. Kan RevJava uitgebreid worden met deze analyses? Voor nullpointer detectie moet dit mogelijk zijn, al is het gevaar dat de analyse te strikt is. Zie onderstaande figuur: Class aclass { aclass(string s) { System.out.println( s.length() ); Figuur 4.5: Moet hier gewaarschuwd worden voor een nullpointer van s? Het bepalen van types in een Vector hangt met name af van wanneer het type van een object bepaald wordt. Als objecten dynamisch aangemaakt worden en dan ook pas het type wordt bepaald, is niet uit de class files te bepalen wat er in de Vector wordt toegevoegd, maar is dit pas runtime te bepalen. Kennis over het design van het programma zou hierbij van pas kunnen komen. Het bepalen van overflows vergt een flow-analyse van het programma. Wanneer er informatie over het design van het programma beschikbaar zou zijn zou de flow-analyse plaats kunnen vinden op slechts een deel van het programma, omdat je dan weet waar een object gebruikt word. 22

Analyse van concurrente programma s kan toegevoegd worden, maar het is minimaal erg moeilijk alle mogelijke problemen op te sporen. Het moet wel mogelijk zijn om op een subset van de mogelijke problemen een analyse te doen. Gevolgen voor RevJava Toevoegen van nullpointer detectie Performance: de performance van RevJava zal weinig veranderen. De check zal zich voornamelijk concentreren op de declaratie/initialisatie en gebruik van het object binnen de klasse of methode waarbinnen de declaratie plaats vindt. class aclass { string[] s; aclass() { void f() { gebruik (s) Figuur 4.6: In de figuur hierboven is s null en wordt in de constructor ook niet gezet, dit zou bij een aanroep op aclass.f() problemen kunnen gaan opleveren. Wanneer s direct te benaderen is door een andere class ( s is niet private) kan dit ook problemen opleveren wanneer die andere class s gebruikt. Metamodel: van een object zal de waarde bijgehouden moeten worden, ten minste of het object geen null is of weer op null gezet is, dit houdt in dat assignments en expressies ook geparsed moeten kunnen worden en in het metamodel moeten. Critics: er zullen regels moeten komen welke aangeven wanneer een nullpointer op zal treden. De moeilijkheid is vooral deze regels niet te strikt te maken. Reader: er moet bekend zijn waar objecten gedeclareerd worden en waar ze gebruikt worden en of het geen null is. Er moeten expressies ingelezen worden. Toevoegen van typebepaling van types in een Vector Performance: Er zal moeten worden gekeken waar de objecten gecreëerd worden, en wanneer hun type wordt bepaald. Hiermee moet rekening gehouden worden dat er met behulp van if..then..else en switch..case statements dynamisch bepaald kan worden wat het type van een object is. Vervolgens moet er gekeken worden wat er met de gecreëerde objecten gebeurd (casten) voordat deze in de Vector worden toegevoegd en of ze ergens ooit veranderd worden. Een (gedeeltelijke) flow-analyse op het programma is noodzakelijk, dit kan de performance sterk negatief beïnvloeden. Metamodel: in een methode zou bijgehouden moeten worden of er conditionele( if..then..else of switch..case ) statements in zitten en wat voor objecten en types deze gebruiken. Dit zijn ook weer expressies. Critics: o Er moet gekeken worden voor welke Vectoren typebepaling relevant kan zijn (b.v.: als er objecten met subclasses in gestopt worden) o Er zal bepaald moeten worden of objecten in die Vectoren dynamisch getypeerd worden Afhankelijk daarvan moet geanalyseerd worden wat voor types in de Vector worden gestopt. 23

Reader: de reader moet inlezen of er sprake is van if..then..else en switch..case statements en op wat voor types deze werken. Toevoegen van overflow analyse Performance: vanwege de benodigde flow-analyse zal RevJava langzamer worden. Wanneer er informatie over het design verzameld kan worden zou de flow-analyse sneller kunnen zijn, maar ook de extractie van het design kost tijd. Deze design informatie zou echter ook voor andere analyses van toepassing kunnen zijn. Metamodel: van variabelen moet hun waarde worden bijgehouden om bijvoorbeeld te kijken of de index binnen de array-bounds blijft. Er moeten weer assignments en expressies bijgehouden worden. Critics: er zal een visitor over de structuur moeten lopen die alle operaties met betrekking tot een object bijhoudt, op deze informatie zal een critic losgelaten moeten worden. Reader: de reader leest bijvoorbeeld ints en hun waarde niet in, deze zouden wel bekend moeten zijn aangezien met behulp daarvan vaak loops afgelopen worden. Er moeten weer expressies en assiginments ingelezen worden. Toevoegen van analyse van concurrente programma s Performance: afhankelijk van hoe diep de analyse moet gaan. Een vrij directe analyse (bijvoorbeeld een simpele deadlock) hoeft niet veel tijd te kosten. Voor een ingewikkeldere analyse (bijvoorbeeld te veel synchronisatie) is misschien weer een flow analyse nodig, en eventueel moet er informatie over het design beschikbaar zijn. Metamodel: er zal misschien extra informatie over het design moeten worden opgeslagen. Critics: er zullen regels gemaakt moeten worden om bijvoorbeeld deadlocks te detecteren op basis van beschikbare informatie. Reader: de reader leest de benodigde informatie al in. Haalbaarheid Toevoegen van nullpointer detectie Het toevoegen van nullpointer detectie in RevJava is haalbaar. Tijdsanalyse: Afhankelijk van de sterkte van de formulering van de regels en hoe diep de analyse moet gaan. Binnen een afstudeerperiode moet er simpele detectie gerealiseerd kunnen worden. Mogelijk afstudeeronderwerp: met prestatieanalyse van RevJava met nullpointer detectie. Toevoegen van type analyse in een Vector Dit is niet onmogelijk maar wel moeilijk, zeker omdat de performance er niet te veel onder zal mogen leiden. Alle mogelijkheden waarop een object dynamisch aangemaakt kan worden ( if..then..else, switch..case, obscure while loops (zie figuur 4.7) e.d.) moeten gecheckt worden evenals de mogelijkheid van casten. De reader zal aangepast moeten worden en het metamodel eveneens. Tijdsanalyse:?? Mogelijk afstudeeronderwerp: eerst moet er goed bekeken worden waar alle mogelijkheden en moeilijkheden liggen, dit was voor ons niet te doen in de tijd die we hadden. 24

class aclass { // x is user-input Vector makeperson(vector v, int x) { while(x>5) v.addelement(new Man()); while(x>0) v.addelement(new Vrouw()); return v; Figuur 4.7: Een voorbeeld van dynamische vulling van een Vector met while loops Toevoegen van overflow analyse Het is mogelijk om te analyseren of bijvoorbeeld een teller niet buiten index van een array gaat binnen een while- of for-loop. Wanneer een array echter dynamisch (bijvoorbeeld door user-input) gevuld wordt of de index met random() wordt aangemaakt moet er veel meer bekeken worden. Er moet dan gekeken worden of de array vergroot wordt, of er elementen verwijderd of overschreven worden. Dit is erg moeilijk en vergt flow-analyse. Tijdsanalyse:?? Mogelijk afstudeeronderwerp: eerst moet er goed bekeken worden waar alle mogelijkheden en moeilijkheden liggen, dit was voor ons niet te doen in de tijd die we hadden. Hele beperkte analyse is waarschijnlijk wel te realiseren. Toevoegen van analyse van concurrente programma s Het toevoegen van makkelijk te detecteren concurrency is te doen. Tijdsanalyse: weer afhankelijk van de mate van analyse, maar binnen een afstudeerperiode voor niet al te moeilijke detectie. Mogelijk afstudeeronderwerp: met prestatieanalyse en een goede afbakening van de te onderzoeken en te implementeren diepte van de analyse. Het is te doen om van deze onderwerpen detectie van een kleine subset van mogelijke problemen in RevJava in te bouwen, zonder dat dit heel erg de prestaties van RevJava erg negatief beïnvloedt. De vraag is natuurlijk of een beperkte analyse van een probleem veel nut heeft. Het is erg belangrijk duidelijk te stellen welke mogelijke problemen buiten de scope van het programma vallen, zodat gebruikers hiervan op de hoogte zijn. Zodra er flow-analyse moet worden gedaan of er informatie over het design bekend wordt geacht, wordt het snel erg ingewikkeld te implementeren en zal RevJava aan performance inboeten. Een verschil tussen RevJava en de meeste andere programma s die type analyse doen is, dat RevJava binaire code gebruikt en de meeste andere uit gaan van de source files. Het is niet zo goed te overzien wat dit verschil voor invloed heeft op de mogelijkheden voor het toevoegen van meer type analyse. 25

5. Design informatie uit de implementatie afleiden Wanneer een systeem geïmplementeerd wordt of evolueert kan het op een gegeven moment niet meer aan het design gaan voldoen. Dit kan problemen opleveren wanneer er later aan het systeem gewerkt moet worden, omdat men dan niet meer van het design uit kan gaan als hulpmiddel. Het zou mooi zijn als vanuit de implementatie het design gecheckt zou kunnen worden. Hiervoor moet de design informatie uit de implementatie worden afgeleid. Design informatie is echter ook handig om analyses niet op de gehele programmaboom, maar slechts op een gedeelte ervan te doen. Stel we willen het type bepalen van Objecten in een bepaalde Vector. We kunnen door het gehele programma gaan zoeken naar relevante operaties, maar als we informatie over het programmadesign hebben kunnen we alleen in relevante classes (met toegang tot de Vector of de class waar de Vector in zit) zoeken. SOUL (Smalltalk Open Unification Language) Een bekend project op dit gebied is SOUL. Soul legt de link tussen design en implementatie met behulp van verschillende lagen. Met behulp van Queries en Rules kunnen bepaalde constraints dan opgevraagd en geanalyseerd worden. SOUL is geïmplementeerd voor Smalltalk, maar het idee is om het ook voor Java en C++ geschikt te maken. Functionele laag Basislaag Programma implementatie Figuur 5.1: Het SOUL lagen model De basislaag is programmeertaal afhankelijk en doet basisoperaties op de programmacode, zoals alle methoden van een class ophalen. De functionele laag maakt gebruik van de basisoperaties uit de basislaag om Queries en Rules op te stellen. Deze functionele laag is niet afhankelijk van de taal waarin het programma geïmplementeerd is. De rules kunnen door de programmeur worden opgesteld naar de eisen waaraan het programma moet voldoen en kunnen gebruikt worden om design te checken. Voorbeeld SOUL: Composite Patterns Als voorbeeld van SOUL geven we het voorbeeld van het detecteren van een zo genaamd Composite Pattern (zie figuur 5.2). Component Operation( ) children Single Composite Operation( ) Operation( ) Figuur 5.2: Het Composite Pattern 26

De composite class is een subklasse van Component en heeft een 1..* relatie met het Component. In de implementatie van de Operation()-methode roept deze recursief de Operation() van de kinderen aan. Er zijn nu een aantal rules die samen dit pattern detecteren: compositestructure, compositeaggregration en compositepattern: Rule { Rule { Rule { deze regel specificeert dat?comp een class is en?composite een subclass is van de?comp Head: Body: compositestructure(?comp,?composite) class(?comp) hierarchy(?comp,?composite) deze regel specificeert dat minimaal 1 methode door?composite wordt overriden en dat daarin recursief wordt aangeroepen op de variabele die de composites bijhoudt Head: compositeaggregration(?comp,?composite,?msg) Body: commonmethods(?comp,?composite,?m,?compositem) methodselector(?compositem,?msg) onetomanystatement(?compositem,?instvar,?enumstatement) containssend(?enumstatement,?msg) deze regel is de combinatie van de voorgaande twee en specificeert een Composite Pattern in een programmastructuur Head: compositepattern(?comp,?composite,?msg) Body: compositestructure(?comp,?composite) compositeaggregration(?comp,?composite,?msg) In dit voorbeeld zijn class(?a) en hierarchy(?a,?b) voorbeelden van functies uit de basislaag. De andere functies maken in hun implementatie gebruik van functies uit de basislaag. 27

RevJava en design informatie Voor RevJava zou het handig kunnen zijn te beschikken over design informatie, zeker in het geval wanneer er flow-analyse noodzakelijk is, omdat met design informatie het gebied voor die flow-analyse mogelijk afgebakend kan worden. Tevens zouden regels gespecificeerd op design de programma-analyse van RevJava kunnen uitbreiden. De informatie die nodig is om regels te definiëren voor design analyse is grotendeels al aanwezig na het inlezen van de class files in het metamodel van RevJava. Het is echter tijdrovend de benodigde informatie voor design analyse te combineren en in regels onder te brengen, hiervoor moet het door RevJava opgebouwde model een aantal keren doorlopen worden. Het zou een idee kunnen zijn om design informatie te genereren op een subset van het model, op het moment dat een gebruiker daarom vraagt. Bijvoorbeeld: een gebruiker bekijkt de analyse die RevJava heeft uitgevoerd op een bepaalde class en is geïnteresseerd in hoe die class in het programma zit, of vermoed dat er nog wel eens extra problemen in die class te verwachten zijn. Hij laat RevJava dan extra (design) informatie over die class genereren. Enkele voorbeelden van zulke informatie (we noemen de betreffende class hier A): Is A onderdeel van een composite pattern? Heeft A objecten in beheer, of wordt A zelf beheerd door een andere class? Is A accessible via een interface, welke methoden van die interface implementeert A en welke niet, welke classes implementeren die interface ook? Op het moment dat een gebruiker de extra informatie over een class laat genereren kunnen er ook analyses plaatsvinden op elementen (fields, variabelen) van die class. We kunnen hierbij denken aan de onderwerpen in het hoofdstuk Type Analyse waarbij flowanalyse gedaan moet worden, zoals nullpointer detectie en typebepaling van objecten in een Vector. De performance van RevJava blijft dan gelijk - afgezien van het inlezen van de extra informatie voor de analyses maar kan op verzoek van de gebruiker extra informatie geven. 28

6. Meta Compilatie Het voornaamste doel van meta compilatie is om eenvoudig compiler extensies om code te analyseren, optimaliseren en transformeren, te kunnen definiëren. Voor RevJava is dit tot op zekere hoogte interessant. Met name de gebruikte technieken om tijdens het compileren bepaalde kritieken los te laten op de files, zijn interessant. Metal Op de universiteit van Stanford heeft een groep onderzoekers onder leiding van Dawson Engler zich met meta-compilatie bezig gehouden. Zij hebben het MC framework ontworpen dat met behulp van een abstracte syntax tree en een control flow graph, dataflow informatie berekent. Op deze informatie kunnen extensies gedefinieerd worden. Het MC framework bestaat uit 2 delen: een taal voor het definiëren van debugging analyses: Metal en een compiler die regels in metal uit kan voeren: xgcc. Met name het laatste is, met oog op RevJava, zeer interessant. Metal is erop gericht om zo flexibel mogelijk te werken, en biedt de gebruiker templates om regels te definiëren. Zo n regel doet het volgende: Ten eerste herkent het interessante source code acties die relevant zijn, ten tweede check het dat deze acties de constraint die de regel oplegt naleeft. Deze zijn bijvoorbeeld van de volgende vorm: Never do X before/after Y of Do X rather than Y. De gedefinieerde regels zijn georganiseerd rond een state machine abstractie. De volgende regel checkt of een pointer die vrij gegeven is nog aangeroepen of nogmaals vrij gegeven wordt: state decl any_pointer v; start: { kfree(v) ==> v.freed; v.freed: {*v ==> v.stop, {err( Using %s after free!, mc_identifier(v)); {kfree(v) ==> v.stop, {err( Double free of %s!, mc_identifier(v)); ; Metal regels definiëren één of meer state machines. Gedurende het uitvoeren van regel, is de huidige staat van de regel de combinatie van de staat waarin alle onderliggende state machines verkeren die de regel definieert. Het aantal state machines groeit en slinkt gedurende de analyse. Elke individuele state machine bestaat uit één globale variabele en één of meer variabelespecifieke toestanden. De globale variabele definiëren een property die door het gehele programma moet gelden. De toestand is houdt de staat van een specifiek object bij. Elke staat wordt toegeschreven aan een instantie van een toestandsvariabele. In het voorbeeld is de variabele-specifieke toestand variabele v. De toestand freed is dan een staat waarin deze variabele kan verkeren. Wanneer v freed is mag niet meer vrij gegeven worden. Gevolgen voor RevJava Deze methode is vooral getest op het debuggen van operating systems en het is, zoals zoveel analyse programma s, gebaseerd op C, en dus is het de vraag of het ook voor Java programma s interessant is. Wanneer we dit bij RevJava gaan doen zullen we tijdens het inlezen van de files de regels moeten toepassen. Daarbij moet echter wel in de gaten gehouden worden dat het soort fouten niet langer uit de metrieken gehaald wordt maar de fouten zullen tijdens het bouwen van de boom gevonden worden. Dit is een heel ander soort fouten dan de fouten die door de Revjava regels gevonden worden dus de bruikbaarheid van deze methode is twijfelachtig. Aan de andere kant is het waarschijnlijk op deze manier ook mogelijk om alle metrieken te verzamelen. Daarvoor is het wel nodig dat de classes in een 29