vrijdag 21 december 2007

AsmProfiler

Ontstaan

AsmProfiler is ontstaan naar aanleiding van mijn ontevredenheid over de profilers die ik gebruikt heb. Ik wilde oa meer details zien, en het moest makkelijk en snel in gebruik zijn. Via een oud-collega (Thaddy, nog bedankt!) kwam ik in aanraking met "detouring". Hiermee kon ik echter nog niet direct een profiler mee maken. Daarvoor heb ik zelf dmv assembly wat meer werk moeten doen. Dit gelukkig gelukt: mijn "proof of concept" werkte!

Werkbare versie, maar nog genoeg te doen...

In het afgelopen jaar heb ik in mijn vrije tijd het concept uitgebreid tot een redelijk werkbare versie. Nog lang al mijn ideeen zijn er niet in verwerkt, dus ik hoop nog veel functionaliteit toe te voegen! Verder is de documentatie nog niet in orde, en de code moet gerefactored/opgeschoond worden (ik heb al veel concept en "hackiediehack" :-) code verbeterd).

Open source

Ik heb het ontwikkeld met de "open source" gedachte: Ik heb zelf te weinig tijd om alles zelf te programmeren, en zelf vind ik dat elke programmeur zonder gedoe een profiler moet kunnen gebruiken. Dus bij deze wil ik iedereen oproepen om mee te helpen met het programmeren :-) .

Google Code

Het project heb ik bij "Google Code" gehost: http://code.google.com/p/asmprofiler/
Daar staan oa een wikki, issue tracker, download list, etc. Tevens regelt Google de opslag etc door middel van "Subversion" als versie beheer systeem. Lekker makkelijk voor mij dus. Wil je mee helpen met de code, dan zul je waarschijnlijk eerst moeten aanmelden, en ik moet je toegang geven tot mijn project. Maar dat zie ik dan wel weer, als er iemand is die belangstelling heeft :-) .

Asmprofiler demo

Ik heb naar aanleiding van een "klacht" op de DDD gelijk een klein demo project gemaakt :-) , dat toont hoe je AsmProfiler in een willekeurig Delphi project kunt gebruiken: http://asmprofiler.googlecode.com/files/DllLoadDemo.zip
http://asmprofiler.googlecode.com/files/DllTestApps.zip

Met C en C++ is het ook gewoon mogelijk om de dll te laden, hier heb ik echter geen C header file oid voor gemaakt. Die moet je zelf even maken adhv de Delphi interface unit.

Dll injection

Als je je programma niet wilt aanpassen, of als je de profiler wilt gebruiken op een programma waar je de code niet van hebt. dan kun de je de "injection" versie gebruiken: http://asmprofiler.googlecode.com/files/AsmProfiler_inject_v10011.zip

Start hiervoor de command line tool "inject.exe", zoek via de "Windows Task Manager" of "Process Explorer" de PID van een programma op, en voer die in. Druk op enter, en de dll wordt via officieele Windows APIs in het programma geinjecteerd :-) . Het scherm van de profiler wordt getoond zodra het geinjecteerde programma "GetMessage" of "Peekmessage" aanroept (normale Windows message loop). Echter, bij sommige programma's werkt dit niet, zoals Open Office.

Gebruik

Als je de profiler dll geladen hebt en het profiler scherm ziet, dan moet je eerst aangeven welke units en functies je wilt profilen door op de "Select items" knop te drukken:

profiler.PNG

Je krijgt dan een scherm te zien met alle units uit de .map file (Delphi -> Project options -> Linker -> Map file -> Detailed). Je kunt ook kiezen om alle (of bepaalde) functies van een geladen dll te selecteren:

selectitems.PNG

Door op "Start" te drukken wordt het profilen gestart, de "Stop" knop stopt het monitoren :-) . Vervolgens kun je via "Show results" de resultaten bekijken:

results.PNG

Dubbelklikken op een item gaat naar het 2e tabblad met meer details.

Disclaimer

Uiteraard is het gebruik volledig op eigen risico :-) . Normaal gesproken moet het geen problemen geven, maar van bepaalde units weet ik dat sommige low level Delphi functies crashes veroorzaken... Zoals de "classes" unit bevat ook adressen naar (het begin van?) classes zelf ipv de functies van classes. Dit moet ik nog uitzoeken. Verder kun je beter de "system" unit ook vermijden: deze bevat veel low level functies. Het beste kun je je "eigen" units gebruiken, en de "Windows" unit is handig omdat het veel standaard Windows APIs bevat.

donderdag 6 december 2007

Delphi speed tips

Na mijn ".Net speed tips" kon een Delphi versie natuurlijk niet uitblijven :-).
Dus bij deze de eerste tips, een tweede (of meer) komen later.

Delphi IDE
De IDE van Delphi kan op een aantal manier versneld worden. Dit betreft de werking van IDE zelf, geen shortcuts etc.

- FastMM memory manager replacement voor Delphi
(http://sourceforge.net/projects/fastmm/)

De makers van FastMM hebben voor Delphi een "replacement dll" gemaakt, die het geheugen beheer van Delphi overneemt. Dit geldt dus alleen voor de Delphi IDE zelf, niet de gecompileerde applicaties (zie onder). Door "borlndmm.dll" te vervangen door de FastMM versie, is de IDE sneller en stabieler (!). Werkt van D5 tot D2005 (D2006 en hoger gebruiken zelf standaard al FastMM!).

- DelphiSpeedUp plugin
(http://andy.jgknet.de/dspeedup/)

Met deze plugin wordt de werking van de Delphi IDE een stuk versneld. Onder andere de opstarttijd is een stuk sneller, maar ook de algehele werking is sneller, doordat interne functies vervangen worden door functies van het Fastcode project (in geheugen, de Delphi .exe wordt niet aangepast). Verder heeft het allerlei interne caches en andere optimalisaties voor een snellere werking. Een echte aanrader!

Delphi experts
Delphi experts zijn plugins waarmee het leven van een programmeur gemakkelijk wordt :-).
Een kleine opsomming van mijn favorieten:

GExperts
(http://www.gexperts.org/tour/)

Dit is een zeer uitgebreide plugin, met zeer veel handige functies. De "experts" zijn verdeeld
over een aantal categorieen:
"Editor experts" - Bijvoorbeeld regels sorteren, reverse statement (!), previous/next identifier (begin/end etc).
"IDE enhancements" - Zoals multiline tabs, component palette verbeteringen.
"Code editor enhancements" - Multiline tabs voor open bestanden, editor toolbar.
"Editor toolbar" - Hierop kun je allerlei functies op plaatsen.

De extra functies die GExperts biedt lopen uiteen van een ASCII tabel tot een zeer goede "Grep
search", van "Set tab order" tot "replace components", van "Project option sets" tot "Project dependencies, van "Clipboard history" tot "Executable information". Verder gebruik ik de "Procedure list" functie erg vaak: CTRL-G indrukken en je krijgt een lijst van alle functies
die een Delphi unit bevat. Default is de subsearch actief: door een gedeelte van een naam in te typen wordt de lijst gefilterd, via "enter" wordt naar de functie gesprongen. Ideaal!

DDevExtensions plugin
(http://andy.jgknet.de/dspeedup/index.php?page=DDevExtensions)

Van de maker van de "DelphiSpeedUp plugin". Bevat een aantal kleine verbeteringen zoals een simpele progressbar tijdens compileren en een "component selector". Maar het meest gebruik ik de sterk verbeterde "View unit" en "View form" functies. Deze werken net als de "Procedure list" functie van GExperts. In dit geval gebruik je de normale CTRL-F12 en SHIFT-F12 sneltoetsen. In plaats van een simpele lijst waarin je alleen op het begin kunt zoeken, krijg je een mooie lijst die je kunt sorteren, filteren op classe, etc. Maar vooral super werkt subsearch: door een gedeelte van een unit/form naam in te typen, waardoor de lijst gefiltert wordt. Ideaal!

JEDI Experts
(http://homepages.codegear.com/jedi/jvcl/)

Deze zijn onderdeel van de JEDI componenten (JVCL, JCL). Deze bevatten een aantal debugger plugins (auto insert JEDI debug data in .exe, threadnames, etc), Project analyzer, Uses wizard etc.

.Net speed tips

Hoewel ik zelf (nog) geen ervaring heb met .Net, vindt ik optimalisaties altijd interresant,
maakt niet uit van wat. Aangezien het officieel .Net blog is (qua naam), kan ik op deze
manier ook wat meer .Net gerelateerde content plaatsen :-).

Speeding Up .NET
(allerlei kleine tips voor snelheidswinst)
http://www.codeguru.com/vb/gen/vb_misc/tips/article.php/c14049/

Strings UNDOCUMENTED
(StringBuilder efficienter dan Strings)
http://www.codeproject.com/dotnet/strings.asp

Arrays UNDOCUMENTED
(waarom one-dimensional arrays sneller zijn dan multi-dimensional)
http://www.codeproject.com/dotnet/arrays.asp

Wat specifieker, mbt Serialization:

Optimizing Serialization in .NET, part 1
http://www.codeproject.com/dotnet/FastSerializer.asp
Optimizing Serialization in .NET, part 2
http://www.codeproject.com/dotnet/OptimizingSerialization2.asp

dinsdag 16 oktober 2007

Adv. debugging: Stack dumps met Process Explorer

In een eerder artikel heb ik uitgelegd hoe je zelf een stack dump kunt maken. Dit vooral bruikbaar bij exceptions, en soms ook voor het debuggen van een bepaalde situatie (”hoe komt hij hier?”).
Maar hoe kun je de stack bekijken als je programma vastloopt? In Delphi kun je het programma pauzeren en de stack bekijken, maar wat als het net buiten Delphi of op een (andere) server draait?

Process Explorer biedt dan uitkomst. Zoals ik al zei in een eerder artikel over Process Explorer: het is een super programma waar ik niet zonder kan. Je kunt er namelijk ook de stack mee bekijken van elke thread van een willekeurig programma. Dubbelklik hiervoor op een programma in de tree van Process Explorer en selecteer de “Threads” tab:

Dubbelklik vervolgens op een thread (hierboven is maar 1 thread) of klik op de “Stack” knop:

Het probleem is echter dat je dan geen beschrijvende namen ziet: alleen bijvoorbeeld een offset van 0×60664 bytes.

De truc hiervoor is om eerst een .map file te maken, en deze naar een .dbg file om te zetten:
Delphi -> Project Options -> Linker -> Map file -> Detailed
(zet ook eerst “optimization” UIT en “Stack frames” AAN op de compiler tab). Druk op “build” om opnieuw het programma te builden en om een map file te krijgen. Vervolgens moet van deze Delphi .map file omgezet worden naar een Windows debug file (.dbg).
Gebruik hiervoor “map2dbg”:
http://www.wischik.com/lu/programmer/ms-dbg.zip
Dit klein programmaatje moet via de command line (bijv. batch bestand) uitgevoerd worden:
map2dbg.exe .
Het bewuste programma wordt dan intern gemarkeerd dat het Windows Debug informatie bevat, en wordt omgezet naar .

Daarna moet in Process Explorer de directory als “symbol path” opgeven waar de bewuste .dbg file staat:
Options -> Configure Symbols

Als je dan een stack dump opvraagt, krijg je wel de volledige namen te zien:

Opmerking: map2dbg lijkt niet (altijd) te werken met Delphi 2007.
Bovenstaande demo lukte met 2007 niet en met Delphi 7 wel…

Soms heb je een nieuwe versie van “dbghelp.dll” en “imagehlp.dll” nodig:
http://msdl.microsoft.com/download/symbols/debuggers/dbg_x86_6.5.3.8.exe

“Now” functie is niet betrouwbaar! (ivm zomer/winter tijd)

In Delphi geeft de functie “Now” de lokale tijd terug. Dit is dus de gecorrigeerde tijd ten opzicht van de GMT of UTC tijd. Oftewel: de lokale tijd is de tijd rechtsonderin op de taakbalk.
Deze tijd is onderhevig aan zomer/winter tijd aanpassingen, wat al dan niet automatisch door Windows wordt aangepast…

Deze functie is dus niet betrouwbaar om de tijd te meten tussen 2 tijdstippen:
je hebt nl een kleine kans (van 2x 1 uur per jaar) dat de tijd 1 uur vooruit of achteruit verspringt ivm zomer/winter tijd. Vooral als kritische onderdelen van je programma hiervan gebruik maakt, is dit belangrijk om te weten!

Oplossing hiervoor is om gebruik te maken van de “GetSystemTime” API van Windows, en niet de “GetLocalTime” die voor “Now” gebruikt wordt.
Ik heb hiervoor een “NowUTC” functie gemaakt:

function NowUTC: TDatetime;
var
SystemTime: TSystemTime;
begin
GetSystemTime(SystemTime);
Result := SystemTimeToDateTime(SystemTime);
end;

Voor wat extra achtergrond informatie:

  • Windows slaat zowieso intern alle tijden als “local” time op. Dus bestanden, logs, etc. Tijdens zomer/winter tijd wissel kan het dus voorkomen dat een bestand opeens 1 uur te oud of zelfs 1 uur te jong (in de toekomst) is! Zie KB van Microsoft:
    “Time stamp changes with daylight savings”

    http://support.microsoft.com/kb/q129574/
  • De “SetLocalTime” API moet je 2x aanroepen om de PC tijd goed aan te passen. De eerste keer wordt nl de tijd eerst gecorrigeerd ten aanzien van de huidige tijd (dus 1 uur erop/eraf als je meer dan een half jaar veranderd) en kan dus 1 uur afwijken. De tweede keer zit je wel in goede winter/zomer tijd zone, en wordt de tijd wel goed gezet.
    Zie KB van Microsoft:
    “SetLocalTime/GetLocalTime Not the Same if Adjusting for Daylight Saving Time”
    http://support.microsoft.com/kb/q234735/
  • Leuk om te melden :-) dat Unix/Linux de tijd intern wel goed geregeld heeft:
    alles is intern GMT/UTC tijd, zodat het geen last heeft van de bovenstaande *kuch* features *kuch* van Windows. Zelfs Windows Vista heeft nog steeds de antieke en onbetrouwbare MS-DOS tijds bepaling! Meer informatie hierover:
    “IBM PC Real Time Clock should run in UT”
    http://www.cl.cam.ac.uk/~mgk25/mswish/ut-rtc.html

Instant Mantis: snel en direct een bug/issue tracking systeem opzetten

Een uitgebreid (!) verslag van een uit de hand gelopen experiment :-) voor het gebruiken van een issue tracking systeem.

Het bedrijf
Ik ben nu dik 2,5 jaar bij hetzelfde bedrijf gedetacheerd, en in die tijd is het bedrijf (ondanks of dankzij :-) ) flink gegroeid. Momenteel zitten we met 50 man in het nieuwe pand omdat het oude veel te klein werd. Niet alleen het bedrijf groeide, ook de projecten zelf groeiden (groter, ingewikkelder, etc).

Werkwijze
Wat niet direct mee groeide waren de werknemers zelf. Nog steeds wordt per project 1 status document in Word bijgehouden (groot, onoverzichtelijk, 1 persoon tegelijk wijzigen, etc). Nu worden daar voornamelijk mechanische dingen van de machines bijgehouden (aanpassingen), of klant/project gerelateerde zaken (wat besteld en geregeld moet worden). Want om alles van software bij te houden is een onbegonnen zaak.

Nu gaat dat meestal wel goed. De Voordelen van een klein bedrijf zijn de korte lijnen en de informele contacten. En de projecten waren nog te overzien. Er is een versie beheersysteem (Borland Starteam) en een eigen framework (met dank aan Aaldert :-) ). Bij problemen wordt de programmeur in kwestie aangesproken: “Als ik dit en dat doe, doet ie het niet meer” -> “Oké, ik zal even debuggen en een nieuwe versie maken”. Echter, niet iedereen houdt consequent een “changelog” bij van wat er bij welke versie veranderd is.

Huidig project
Momenteel werk ik aan een machine die nu bij 2 klanten staat: 4 in Duitsland en 2 in Engeland. En op de zaak zelf staat een proto type (voor testen). De laatste tijd hield ik de meeste dingen bij in de email: “Ik heb een probleem”, “Kun je dit en dat even voor me doen of maken?” -> “Stuur maar een email, anders vergeet ik het”. In Outlook gaf ik dan een vlag aan emails die ik af moest handelen. Dingen die mij te binnen schoten, schreef ik op een kladblok, of hield ik in een draft e-mail bij. Maar met 2 klanten die al met de machine werken (dankzij “Agile development” in plaats van de “Waterfall methode” :-) ) kreeg ik vaak de vraag (van projectleider) of iets al opgelost was, en zo ja in welke versie. Dankzij de changelog kon ik daar wel een antwoord opgeven, maar alleen ik had dus eigenlijk het overzicht.

Op zoek naar iets beters…
Natuurlijk wist ik wel dat het beter/anders kan en moest, maar je past je al gauw aan aan het bedrijf en komt in een bepaalde sleur vast te zitten (druk genoeg met programmeren, bug fixen, etc). Toen een nieuwe klant erbij kwam (in Nederland, met weer andere eisen & wensen) en de vakantie dichterbij kwam, werd het voor mij duidelijk: zo kan het niet meer, dit moet ik anders gaan doen. Ik ben toen op Internet wezen zoeken naar een bug/issue tracking systeem. Nu schrok ik een beetje van het aanbod: welke moest ik kiezen, en kon niet alles uitproberen (geen tijd). 1 naam kwam ik een aantal keren tegen, met goede recensies: Mantis. Op 1 site kreeg het zelfs een cijfer 9. Na wat zoeken op de site (http://www.mantisbt.org/) kwam ik “Instant Mantis” voor Windows tegen, wat precies voor mij geschikt was!

Instant Mantis
Mantis is een (open source) issue tracking systeem. Op site downloade ik gratis :-) de 20mb zip, wat na uitpakken 70mb groot bleek te zijn. In de hoofddirectory vond ik 2 batchbestanden: 1 om te starten en 1 op te stoppen. Zo simpel is het. Bij het starten wordt automatisch MySQL (database) en Apache (website) gestart. Default start Apache op poort 8008, maar dit kon in het batch bestand eenvoudig aangepast worden naar 80. Firefox opgestart en ik kon direct aan de slag. Alles kan/moet via de webpagina ingesteld en aangepast worden: projecten, users, issues, etc.

Bugs en todo’s worden als “issues” ingevoerd. Hierbij kunnen de standaard velden ingevoerd worden: priority, severity, description, notes, attachments, status, etc. Er kunnen ook eenvoudig “custom fields” aangemaakt worden, bijvoorbeeld een required “customer” veld met een lijst van klanten waarvoor een issue geldt. Gebruikers krijgen automatisch een e-mail bij een nieuwe issue, en de “poster” krijgt e-mails terug als de status veranderd (fixed,feedback), notitie is toegevoegd, etc.

Acceptatie
Eerst wilde ik gewoon voor mezelf gebruiken en uitproberen. Ik liet het even vallen bij een (assistent) projectleider bij de klant op locatie (heeft VPN verbinding naar de zaak zelf). Deze was meteen geïnteresseerd en heb hem toen de computernaam opgegeven waarop het draaide (vmware build server). Na 1 dag proberen was hij helemaal enthousiast en moest voor hem ook de andere machines bij die klant als projecten toevoegen, en de nodige users voor die projecten. Hij kan precies zien welke bugs en todo’s openstaan, krijg bericht als iets in een volgende versie gefixed is, etc. Alles kan nu precies gevolgd worden (evt discussies via notes, extra info via attachments, automatische changelog voor een versie etc. Na nu een week draaien willen hij en ik niet meer anders :-). Steeds meer mensen gaan het nu gebruiken, en zijn enthousiast. Er is vorige jaar iets vergelijkbaars geprobeerd met T-Plan, maar dit beviel erg slecht: traag via VPN, onoverzichtelijk en onduidelijke GUI (op een label klikken om editbox te krijgen…) en te beperkt.

Huidige status
Na de vakantie heeft Mantis zich steeds verder verspreidt over het bedrijf. Ondertussen is het duidelijk geworden dat dit officiëler gebruikt moet gaan worden. In plaats van dat het draait op een van de vmware build/release images, moet het natuurlijk op een “echte” interne server draaien, en ook voor buitenaf via de website bereikbaar zijn (in plaats van alleen via VPN).

Toekomst
Voorlopig zal Mantis nog wel gebruikt worden :-). Het biedt bovendien perspectieven voor de toekomst. Er zijn namelijk verscheidene 3rd party koppelmogelijkheden zoals test management en project en release management. Bijvoorbeeld de test scripts worden in het test management pakket ingevoerd, en als een test faalt of opmerkingen zijn, dan worden deze als issues in Mantis ingevoerd en gekoppeld.
Maar het is ook mogelijk dat eerst een uitgebreid onderzoek gedaan wordt naar andere mogelijkheden, omdat Mantis 1 van de vele pakketten is. Voorlopig voldoet het echter prima.

Discussie
Hebben anderen ook dergelijke ervaringen? En wat gebruiken jullie zelf? Hebben jullie nog aanbevelingen of tips?

woensdag 19 september 2007

Adv. debugging: hook all exceptions!

In mijn vorige artikel schreef ik hoe je een “stack trace” kunt maken. Maar soms is dat niet genoeg. Je krijgt bijvoorbeeld een ongrijpbare “Catastrophic failure” of de stack trace geeft niet precies de echte exceptie weer. Dit komt omdat een stack trace niet goed werkt als deze in een try..except (of try..catch in C) afgevangen wordt. Als je namelijk onderstaande code probeert:


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

Een van de programma's die ik *moet* hebben bij (Windows) problemen is 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:
Proces details
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:
Verder kan in de tab "Threads" een lijst opgevraagd worden met informatie per thread (CPU, priority, etc).

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:
Ik kan nog wel een poos allerlei andere handige dingen vertellen over dit superprogramma, maar nog even kort:
- 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

Google Code (http://code.google.com/) is een portal van Google waarop allerlei code gerelateerde zaken staan. Zo kun je zoeken naar bepaalde (open source) code, Google API's downloaden, etc.

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:
  • een google account (zoals GMail)
  • en natuurlijk een project :icon_cool:
  • SubVersion client

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):

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 :icon_wink:

Google Reader: rss & nieuws & blog reader

Zelf gebruik ik het nu een al poosje en het bevalt me goed.
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?
:icon_smile:

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...