woensdag 19 september 2007
Adv. debugging: hook all exceptions!
…
try
raise Exception.Create(’hier gaat het fout’);
except
raise; //deze regel geeft stack trace weer
end;
…
dan geeft de stack trace niet de 2e regel (Exception.Create) aan als de plek waar het fout ging, maar de 4e, waar de exception opnieuw geraised wordt. Nu is het in het bovenstaande voorbeeld wel duidelijk waar het fout ging, maar niet als de code groter is en geneste procedures heeft.
Ik heb dit namelijk zelf vaak meegemaakt. Dan dacht ik: ik heb een mooie exception handler met stack trace gebouwd, nu kan ik alle fouten precies lokaliseren en oplossen. Maar kwam ik menigmaal bij een stack trace uit op een try..except combinatie… Dan weet je nog niet waar het fout ging (vooral als het geen code van jezelf is, waar je de try..except kunt aanpassen).
Gelukkig kwam ik een andere JEDI unit tegen: JclHookExcept.pas. Hiermee is het mogelijk om ALLE exceptions binnen te krijgen! Het maakt namelijk een exception hook: de “RaiseException” functie van “kernel32.dll” wordt omgeleid (detouring, hier hoop ik ook een stuk over te schrijven) naar een eigen functie. Omdat hier alle fouten binnen komen, voordat ze door een try..except afgevangen worden, kun je deze fouten eenvoudig loggen!. Als je dan vaak smerige trucs toepast zoals:
try
i := StrToInt(string);
except
i := -1;
end;
dan val je gauw door de mand: de Econversion exception komt dan netjes via de exception hook binnen :-).
Wat ik vooral handig vind met deze exception hook, is dat je “verborgen” fouten in bijvoorbeeld dll’s kunt traceren, of “Catastrophic failures” kunt achterhalen. Voor dit laatste heb ik een voorbeeld gebruikt van een QC posting: http://qc.borland.com/wc/qcmain.aspx?d=6069
Hieraan heb ik de volgende code toegevoegd:
…
uses
JclDebug, JclHookExcept;
…
procedure AnyExceptionNotify(ExceptObj: TObject; ExceptAddr: Pointer; OSException: Boolean);
var
sError:string;
begin
if ExceptObj is Exception then
begin
sError := Format(’%s at adress %p: %s’,
[ExceptObj.ClassName, ExceptAddr,
(ExceptObj as Exception).Message]);
if OSException then
sError := ‘OS ‘ + sError;
sError := ‘HOOK: ‘ + sError;
MessageDlg(sError, mtError, [mbOK], 0);
end;
end;
initialization
JclStartExceptionTracking;
JclAddExceptNotifier(AnyExceptionNotify);
Dit geeft bij het uitvoeren de volgende afgehandelde fout:
—————————
Error
—————————
HOOK: Exception at adress 0047D639:
IErrorServer.RaiseServerError
Error at server side
—————————
OK
—————————
Normaal zou je alleen “Catastrophic failure” krijgen!
dinsdag 4 september 2007
Favoriet programma 2: Total Commander
Total Commander is het meest gebruikte Windows programma door mij (naast Delphi en Firefox :-).
Het is typisch zo’n programma waarvan je moet houden: je vind het super of je vindt het niets.
Total Commandor is een bestandsbeheer programma, als vervanger voor Windows Verkenner.
Het is een cloon van uit het dos tijdperk bekende Norton Commander. Het belangrijkste kenmerk is
de dubbele weergave van directories (naast elkaar). Dit heeft grote voordelen, omdat je zo eenvoudig bestanden
kunt kopieren van de ene directory naar de andere. Of de bestanden vergelijken, een selectie maken en
deze inpakken, etc. Zip bestanden kunnen net als directories bekeken en genavigeerd worden. Op dezelfde
manier kan ook via de ingebouwde FTP client bestanden geup- en download worden.
Een screenshot als voorbeeld:
Sinds de laatste versie is ook tab-support toegevoegd, net als Firefox en IE7. Hierdoor kun je nog
makkelijker meerdere directories open hebben en vergelijken.
Verder onderscheidt het zich door een snelle en krachtige zoekfunctie (eentje die WEL werkt, in
vergelijking met F3 van Verkenner…). Het resultaat kan ook als directorie bekeken, opgeslagen,
verwijderd, gekopieerd, ingepakt, etc worden.
Selecties kunnen eenvoudig gemaakt worden met de muis of toetsenbord, en op basis van een gedeelte
van een naam. Door de + te gebruiken wordt een nieuwe selectie toegevoegd, met de - verwijderd.
De kopieer functie is ook handig en krachtig: alles overschrijven, alleen oude bestanden, alles overslaan, etc.
Daarnaast kunnen veel acties (kopieren, inpakken, downloaden) op de achtergrond (in een thread) uitgevoerd
worden, zodat je ondertussen gewoon door kunt werken!
De ingebouwde viewer verdient ook aandacht: het ondersteunt verschillende bestandtypes en weergave modi
(oa hex). Maar vooral grote bestanden kan het moeiteloos inlezen: alleen bijvoorbeeld het begin of einde wordt
ingelezen, zodat een tekstbestand van 2Gb direct getoond wordt!
Naast de normale browse functionaliteit heeft het onder de motorkap veel andere handige tools en functies, zoals:
- multi rename tool
- split/combine files (!)
- CRC check
- file/directorie comparing
- plugins
- etc
Maar alle voordelen hebben ook een nadeel: het is geen gratis programma. Maar het is wel als shareware te gebruiken.
Je moet dan bij het opstarten willekeurig en 1,2 of 3 in toetsen. Dus gelukkig geen tijd controle of andere
beperkingen. Zelf heb ik op een gegeven moment het programma gewoon gekocht (als 1 van de weinige).
Maar hoe zit het dan Linux, zal misschien iemand denken? Daar werkt Total Commander ook! Echter wel
via Wine, en je moet eventueel een aantal fonts installeren. Maar verder werkt het als een zonnetje.
Kortom, Total Commander is echt een tool voor programmeurs, want dan gebruik je veel tekst bestanden, directories,
zip bestanden, zoeken en vergelijken, etc. En dan kun je veel van de functionaliteit goed kunnen gebruiken.
Laat ik tot slot een discussie uitlokken door de stellen: je bent geen goede programmeur zonder Total Commander!
Ik hoop een volgende keer een aantal plugins te bespreken, want deze geven Total Commander nog meer
functionaliteit.
Adv. Delphi debugging: Exception stack trace
Je kent het wel, je bent zelf je code aan het testen op een andere pc of door gebruikers c.q. testers,
en je krijgt allerlei ongrijpbare “acces violations”, ontraceerbare “index out of bounds” etc.
Normaal kun je in Delphi deze fouten debuggen, onder andere met de “stack view”, maar die heb
je niet op het test systeem staan.
Als oplossing hiervoor is de jclDebug unit van JEDI library:
http://sourceforge.net/projects/jcl
Met het volgende commando zet je “exception tracing” aan:
jclDebug.JclStartExceptionTracking
Om de stack trace bij een exception uit te lezen:
jclDebug.JclLastExceptStackListToStrings(str, True, True, True);
Bijvoorbeeld:
procedure TForm1.FormCreate(Sender: TObject);
begin
jclDebug.JclStartExceptionTracking;
Application.OnException := HandleException;
end;
procedure TForm1.HandleException(Sender: TObject; E: Exception);
var
str:TStrings;
begin
str := TStringList.Create;
jclDebug.JclLastExceptStackListToStrings(str, False, False, True);
MessageDlg( e.Message + #10#13 + str.Text, mtError, [mbOK], 0 );
str.free;
end;
Je zou dan bij een error het volgende kunnen krijgen:
EAccessViolation with message ‘Access violation at address 00403924. Read of address 2009FFD4′.
[00403924] System.TObject.ClassName (Line 8726, “sys\system.pas” + 3)
[0046A8AC] frmMain.TForm1.DoSomethingStupid (Line 77, “frmMain.pas” + 1)
[0046A88A] frmMain.TForm1.DoSomething (Line 72, “frmMain.pas” + 1)
[0046A877] frmMain.TForm1.btnTestClick (Line 67, “frmMain.pas” + 1)
…
Bij een stack trace is de bovenste altijd de laatste en nieuwste item, je moet dus van
onderen naar boven lezen. Dan zien we dat we op “btnTest” geklikt hebben (”btnTestClick”), waardoor
procedure “DoSomething” uitgevoerd werd. Deze voerde “DoSomethingStupid”, die de “ClassName” opvroeg
van een niet-bestaand object. Dit had een “acces violation” tot gevolg.
Dit geeft een duidelijk beeld wanneer en hoe de fout tot stand kwam. Zelf dump ik als deze informatie
in een log bestand en niet op het scherm (gebruikers schrikken daar zo van ), zodat ik eenvoudig
alle stack traces van de fouten kan bekijken.
Dit is nog maar een enkele mogelijkheid van de jclDebug unit: het bevat nog meer handige debug functies,
maar die kan ik hier niet allemaal behandelen. Speel er eens mee, zou ik zeggen.
maandag 2 juli 2007
Favoriet programma 1: Process Explorer
http://www.microsoft.com/technet/sysinternals/utilities/ProcessExplorer.mspx
Het is een erg krachtig en veelzijdig programma, dat bijna alles over Windows en processen naar voren kan toveren.
Het is freeware, en een poosje terug is de site en makers ervan (met alle andere tools) door Microsoft overgenomen.
Hoofdscherm
In het hoofdscherm worden de processen in een treeview getoond (parents met child processes).
Standaard wordt er een CPU kolom getoond met proces beschrijving, maar dit kan ook uitgebreid worden met alle (?) informatie wat vanuit
Windows erover opgehaald kan worden.
Optioneel kan onderin het scherm per geselecteerd proces een lijst met alle handles (files, registry, etc) of geladen dll's getoond worden:
Door te dubbelklikken op een proces, kan een apart scherm opgevraagd worden met alle details over het proces.
Deze zijn onderverdeeld in een aantal tabs, waarbij de "Performance Graph" tab een mooi overzicht laat zien van
de CPU, geheugen en I/O in de tijd:
Systeem overzicht
Bovenin het hoofdscherm wordt in een grafiek de status van het systeem getoond. Door hierop te dubbelklikken wordt
wederom een detail scherm geopend, met ook informatie per cpu/core:
- sessie overzicht van ingelogde gebruikers (handig op Windows 2003 servers)
- vervangen van standaard Windows TaskManager (tip!)
- reboot/shutdown van pc (erg handig met Remote Desktop)
- highlight duration: nieuwe processen per seconden groen, afgesloten processen rood
Ik zou zeggen, probeer het eens uit. Als je er een poosje mee gewerkt hebt is de standaard taskmanager zo gigantisch
beperkt en onhandig!
Ik hoop trouwens een volgende keer een artikel te schrijven hoe je een process kunt debuggen met Process Explorer!
vrijdag 29 juni 2007
Google Code: project hosting
Project hosting
Maar het heeft (al sinds een poos) ook als service "project hosting". Je kunt dus bij Google Code je eigen (open source) project onderbrengen.
Het enige wat je nodig hebt:
SubVersion Client
Als versie beheer systeem wordt SubVersion gebruikt. Daarom heb je ook een SubVersion client nodig.
Wat ik zelf als Windows client gebruik, is RapidSVN: http://rapidsvn.tigris.org/
Dit is een grafische schil om de algemene SubVersion library heen. Deze heb je dus ook nodig:
http://subversion.tigris.org/project_packages.html
Voor meer info, zie ook: http://code.google.com/p/asmprofiler/wiki/Subversion
Code downloaden
Om een project uit te checken (oftewel: code downloaden) moet je de volgende acties doen (in RapidSVN):
- Start RapidSVN, menu "Repository", kies "Checkout"
- Vull een URL in, bijv: "https://asmprofiler.googlecode.com/svn/trunk"
- Vul lokale doel directory in en druk op OK
Zelf heb ik een klein beginnend project bij Google Code: AsmProfiler (http://code.google.com/p/asmprofiler/).
Het is een werkende profiler (als dll), waarbij je alleen de dll hoeft te laden (dus geen enkele regel code aanpassen!).
Het is echter nog wel in "proof of concept" fase, dus ik moet nodig de boel refactoren met Delphi 2007
Google Reader: rss & nieuws & blog reader
Moest ik voorheen elke keer langs een aantal interessante sites browsen om te kijken of er nieuwe items waren, bij Google Reader kun je al deze sites onderbrengen in 1 centrale plaats. De sites moeten dan wel RSS ondersteunen, bij Firefox kun je dit zien aan het oranje icoontje rechts in de adresbalk.
Google Reader ververst elke 5 minuten of zo deze "RSS feeds", en laat de nieuwe item vetgedrukt zien. Zo zie je in 1 oogopslag of er nieuwe items zijn. Ideaal als je verschillende aantal soorten sites hebt, anders moet je zelf bepalen of er andere items op een site staan sinds je vorige bezoek.
Gemak dient de mens toch?
Zo een paar sites waarvan ik abonnee ben:
Programming:
CodeGear Blogging Community
Coding Horror
Craig Stuntz's Weblog
Steve Trefethen's Weblog
The Delphi Geek
Algemeen:
Slashdot
Tweakers.net Mixed RSS Feed
OpenSource Nieuws Nederland
Als iemand anders nog leuke site/links/blogs heeft: laat het me weten!
Oh ja, de 4dotnet blog heeft ook een rss feed: http://www.everything4dotnet.nl/blogs/rss/
Maar die werkt op dit moment nog niet...