...someplace, where there isn't any trouble? Do you suppose there is such a place, Toto?

64 bit Windows - Teil 4

Bevor jemand auf die Idee kommt, daß die Serie über 64-bit Windows schon beendet ist, geht's nun weiter. Wir wissen bereits, daß die einzige Hardwareplattform für x64, die mittelfristig weitere Verbreitung finden wird, die AMD64/EM64T-Plattform ist und nicht IA64. Weiterhin wissen wir, daß man aus der Kombination mit aktuellem PlatSDK (das Windows 2003 SP1 PlatSDK) und VC6 eine Entwicklungsumgebung zustande bringt. Was wir noch nicht wissen, ist, was man ändern muß um auch einen sauberen Build für x64 hinzukriegen. Und darum geht es in dieser Folge.

Wir fangen an, indem wir erstmal mit dem Projektwizard aus VC6 ein Projekt erzeugen. VC6 starten wir dazu nicht bereits jetzt wie in der letzten Folge beschrieben aus einer PlatSDK Buildkonsole, sondern starten msdev "ganz normaaaaal" (Roy Makaay) aus dem Startmenü. Wir nehmen auch erstmal kein MFC-Projekt, sondern ein Projekt vom Typ "Win32 Application". Als Untertyp wählenden wir "A typical "Hello World!" application". Was eine typische Hello-World-Application ist, hat sich mir zwar bis zum heutigen Tag noch nicht vollständig erschlossen, aber wie sie ausschaut ist klar: Eine Applikation mit GUI, Messageloop und indirektem (event-driven) Zeichnen in der Client-Area des Applikationsfensters, dazu ein Menü, über das die Applikation beendet werden kann oder eine modale Dialogbox angezeigt werden kann. Wir erzeugen also das Projekt und übersetzen es einmal im Win32 Debug Build, um sicherzugehen, daß das Projekt auch wirklich einwandfrei buildet. Nun beenden wir msdev wieder.

Jetzt starten wir eine PlatSDK Buildconsole. Zu diesem Zweck wählen wir aus dem Startmenü den Eintrag "Microsoft Platform SDK for Windows Server 2003 SP1" -
"Open Build Environment Window" -
"Windows XP 64-bit Build Environment" -
"Set Windows XP x64 Build Environment (Debug)"
worauf sich eine Konsole öffnet. Von hier aus starten wir msdev.exe mit dem Kommandozeilenparameter /useenv. Da drin checken wir zur Sicherheit nochmal ab, ob auch wirklich die korrekten Pfade verwendet werden. Wir wählen zu dem Zweck den Menüpunkt "Tools" - "Options" aus. Der sechste Tab in diesem Property Sheet heißt "Directories". Wenn hier für "Include files" und für "Library files" Pfade aus dem PlatSDK drin stehen, dann paßt alles.

Als erstes fügen wir nun erstmal einmal neue Buildtargets hinzu. Unter "Build" - "Configurations..." fügen wir ein Target "x64 Debug", ausgehend vom Debug Build, und ein Target "x64 Release", ausgehend vom Release Build, hinzu. Dann wechseln wir zum Target "Win32 x64 Debug" und öffnen für unser Projekt die "Project Settings". Unter C/C++ ändern wir erstmal unter "General" die Debug Info von "Program Database for Edit and Contimue" ab auf "Program Database". Als nächstes gehen wir auf die Kategorie "Code Generation" und wählen statt einer single-threaded runtime eine multithreaded runtime. Dann gehen wir in das mehrzeilige Editfeld mit dem Label "Project Options" und editieren. Ja, da drin darf man auch editieren. Wir schmeißen die Option /GX und /GZ raus und ergänzen stattdessen die Optionen /EHsc und /Wp64. Nun gehen wir auf den Linker Tab und die Kategorie "Debug". Dort entfernen wir das Häkchen bei "Separate Types". Schlußendlich gehen wir auch hier in das mehrzeilige Editfeld "Project Options" und ergänzen am Ende (wichtig: AM ENDE!) /machine:AMD64. Nun machen wir einen "Rebuild All" für dieses Target. Wir werden zwei Compilerwarnungen erhalten und Gazillionen von Linkerfehlern vom Typ "unresolved external symbol __security_cookie". Um den Linkerfehler zu beseitigen müssen wir nämlich noch eine lib ergänzen, die man unter x64 praktisch immer für die C-runtme braucht. Zu dem Zweck gehen wir wieder auf die Project Settings und ergänzen im Link-Tab unter der Kategorie "Input" im Feld "Object/library modules" die library bufferoverflowu.lib. Die beiden Warnungen kriegen wir mit einfachen casts zu int weg, sie rühren daher, dass ein WPARAM keine 32-bit mehr breit ist wie ein int und dass strlen einen size_t zurückliefert, der auch keine 32-bit mehr breit ist. All diese Schritte können wir nun auch für den x64 Releasebuild ausführen. Wer bis jetzt gut aufgepaßt hat, wird feststellen, daß ich bisher noch nichts drüber geschrieben habe, daß wir eigentlich auch eine x64-Maschine zum Entwickeln brauchen. Und in der Tat, alles bisher läßt sich auf einer normalen x86-Umgebung durchführen, weil die x64-Compiler des PlatSDKs Cross-Compiler sind und eigentlich x86-Binaries. Aber wenn wir nun einmal unser Binary ausführen oder debuggen wollen, brauchen wir natürlich spätestens jetzt eine Kiste auf der die x64 Edition von XP oder dem W2K3 Server läuft. So, das nächste Mal schauen wir uns an, was es damit auf sich hat, daß ich erstmal kein MFC-Projekt machen wollte und wir schauen uns die Situation an, wo wir VC6 auf einer x64-Edition von XP/W2K3 Server ausführen und unser Binary auf dieser Plattform debuggen wollen.

Herzige Bilder von KIH

Diese Bilder sollten IMHO einer breiteren Öffentlichkeit nicht mehr länger vorenthalten werden:

...und auch das ist lustich:

Krass! Stell Dir vor Dirkie bloggt und keiner kriegt's mit!

Mannomann, Der Dirkie und sein Blog war ganz offensichtlich der erste aus der Entwicklerriege von επτ€σ, nicht die schmutzigen alten Männer aus Mission Control. Und nein, wir haben uns nicht abgesprochen!

Saavik - Meine eigene x64 Box

Und ein weiterer kleiner Einschub, bevor es mit der großen 64-bit Windows Reihe weitergeht, aber diesmal thematisch eigentlich ganz passend.

Besucher in Mission Control haben gesehen, daß bei mir zwei Maschinen am Platz stehen. Eine davon ist eine fast 4 Jahre alte P4-Maschine mit 1GB RAM, mit der ich meine Hauptarbeit erledige. Daneben steht eine mittlerweile 3/4 Jahr alte Maschine mit einem frühen Athlon64 die mit der x64 Edition von XP RTM läuft. Leider kann ich diese Maschine nicht wirklich nutzen, weil ich darauf kein VMWare 4 zum Laufen kriege, erst die 5er Version von VMWare unterstützt auch 64 bittige Hosts. Und mit VMWare 5 bei επτ€σ ist das ja so eine Sache, "but that's a whole different kettle of fish".

Daheim in Crailsheim habe ich seit gut einer Woche ein feines kleines Maschinchen, das meinen Park an Rechnern ideal ergänzt. Es ist der Rechner, den Fujitsu-Siemens z.Z. als "Deutschland-PC" vercheckt und ist, soweit ich das Ganze beurteilen kann, ein beachtliches Stück Hardware für einen äußerst moderaten Preis von 999 Euros. Die Maschine läuft mit einem Dual Core Athlon64X2 mit einem Quantispeed-Rating von 3800 und einem NVidia nForce4-Chipsatz, besitzt leider nur 1GB RAM (das bleibt nicht lange so, isch' schwör!), aber hat dann so Highlights wie eine 250GB Serial-ATA Festplatte, DVD Writer und TV-Karte. Vorinstalliert kommt eine XP Media Center Edition mit SP2, also ein herkömmliches x86-Betriebssystem. Inwieweit sich die Media Center Edition von XP Professional oder XP Home unterscheidet, weiß ich ehrlich gesagt gar nicht, für mich sah das Ganze wie eine Professional aus, denn während nach dem erstem Einschalten das Setup komplettiert wurde, wurde angeboten, eine Domain zu joinen. Wie auch immer, die Media Center Edition wurde von mir genau 4mal gebootet und seither nimmer. Das erste Mal, um das Setup zu komplettieren, das zweitemal um mit wupdmgr.exe alle Patches draufzuspielen, das dritte Mal um mit einem geeigneten Tool die am Stück formatierte Festplatte neu zu partitionieren und die Media Center Edition auf die ersten 80GB einzudampfen, und das vierte Mal, um die beiden neuen 80GB Partitionen zu formatieren. Ab da wurde die x64 Edition RTM von XP eingespielt und oh Wunder: Das Setup lief ohne einen Muckser und problemlos durch. Da auf heise online ein Artikel über den Rechner kam, in dem erwähnt wurde, daß darin eine OEM-Version des Asus A8NE verbaut wurde, schnell auf asus.com.tw und dann die nächste Überraschung: Alle Treiber für das Mobo gibt's auch als x64-Versionen und sind WHQL-zertifiziert. Die einzige Hardware, für die ich bis jetzt noch keinen x64-Treiber gefunden habe, ist die TV-Karte.
Aber das interessanteste für den geneigten Leser ist sicherlich die Frage: Wie schnell ist das Biest? Also habe ich jetzt mal einen kleinen Testparcour gemacht um zu sehen, wie sich die Kiste mit anderen Rechnern, die ich so habe (inklusive der beiden Rechner an meinem Arbeitsplatz) so schlägt. Der Testparcour besteht aus:

  • CHEKOV Meine Dual Celeron 466 Kiste in Crailsheim mit W2K Professional SP4. Eigentlich meine Lieblingsmaschine weil meistens ausreichend schnell und mit 2 Prozessoren auch flink im UI wenn's mal auf einem Prozessor wieder etwas länger dauert.
  • SULU Mein PIII Coppermine mit 1 GHz Takt und nur einem Prozessor und 1.5 GB RAM. Auf ihm läuft XP Professional. Eine identische Maschine (SPOCK) steht in meiner Hütte in Bernhausen direkt neben επτ€σ.
  • PICARD Mein Notebook mit einem Pentium M 1300 und 768 MB RAM, auch mit XP Professional
  • SAAVIK Besagte neue x64 Maschine
  • ES-ES128 Meine steinalte Single Processor P4-Maschine bei επτ€σ und Quell' aller meiner Leiden bei der täglichen Arbeit
  • C64 Mein Single Processor x64 bei επτ€σ mit einem Athlon64 3200 und 1.5 GB RAM und einem NVidia nForce3-Chipsatz

Mein "Benchmark" bestand darin, mit VC6 den aktuellen Build des επτ€σ Management Agents komplett im Debugbuild zu übersetzen. Und hier die Zeiten:

Chekov359s
SULU152s
PICARD107s
SAAVIK57s
es-es128156s
C6455s

Man sieht also, daß erstaunlicherweise SAAVIK geringfügig langsamer ist als C64. Keine Ahnung woran das liegt, vielleicht liegt es daran, daß auf SAAVIK bereits mehr im Hintergrund läuft, wie etwa die VMWare 5.5 Beta, aber wahrscheinlich ist das I/O Subsystem von C64 einfach etwas schneller, evtl. ist die Festplatte bei SAAVIK einfach langsamer. Aber wenn man dann mal die Prozessorlast von beiden Maschinen vergleicht, wird man feststellen daß SAAVIK im Mittel zu etw 45% ausgelastet ist während des Builds - das ist ja auch klar, ein Build ist eine sequentielle Aufgabe und kann so ohne weiteres nicht parallelisiert werden und beschäftigt damit weitestgehend nur einen der beiden Cores. Anders bei C64: Während des Builds "steht" die Maschine weil sie, wenn sie nicht gerade auf I/O wartet, zu 90 bis 100% ausgelastet ist. Man kann also davon ausgehen, daß sich aufgrund der beiden Cores von SAAVIK das Ergebnis schnell wandelt, wenn beide Maschinen gleichzeitig beispielsweise noch eine VMWare Session hosten müßten.

Das interessanteste ist aber, daß ich mit SAAVIK, SPOCK, SULU und PICARD nun mittlerweile 4 Maschinen mein Eigen nenne, die schneller sind als mein Arbeitsplatzrechner bei επτ€σ. Scheint so, als wäre mein Stundensatz noch nicht hoch genug, das gibt Munition für die nächsten Gehaltsverhandlungen :-)

(Edited: Zeiten von CHEKOV von 559s auf 359s korrigiert, Typos fixed)

Was zur Hölle ist strsafe.h?

Jetzt mal ein kleines Intermezzo in der 64-bit Serie:

Heute wurde ich von einem Kollegen darauf hingewiesen, daß mein Code bei ihm nicht buildet, weil eine Datei strsafe.h nicht gefunden werden kann. Es stellte sich im weiteren Zweierlei heraus. Zum einen war bei dem Kollegen gerade das Netzlaufwerk weg, wo das W2K3 Server PlatSDK liegt, deshalb konnte über den include-Suchpfad die strsafe.h nicht gefunden werden, ich war also erstmal aus dem Schneider. Zum anderen aber offenbarte der Kollege, daß ihm der Zweck dieses Headerfiles nicht bekannt war. Wir beschlossen daher gemeinsam, daß ich darüber Bloggen sollte.

Die Datei strsafe.h ist ein Headerfile, das eine Riesenmenge an Funktionen für sicheres Stringhandling beinhaltet. Im Prinzip sind das alles inline-Funktionen, die sichere Wrapper rund um die Standard-C-runtime Funktionen wie sprintf und seine Freunde bietet. Darum ist strsafe sehr unkompliziert anzuwenden, weil man keine lib braucht und alles portabel in diesem einen Headerfile implementiert ist, das man lediglich nach den Headern der Runtime includieren muß. Das Ziel von strsafe.h ist es, die als unsicher verschrienen C-Runtime-Funktionen wie strcat, strcpy, gets, sprintf, strlen, vsprintf durch sicherere Varianten zu ersetzen, mit denen kein buffer overrun, sei es durch user input oder durch fehlerhafte Programmlogik entstanden, mehr möglich ist. Oder aus der msdn Doku zitiert:

"The advantages of the Strsafe functions include:

  • The size of the destination buffer is always provided to the function to ensure that the function does not write past the end of the buffer.
  • Buffers are guaranteed to be null-terminated, even if the operation truncates the intended result.
  • All functions return an HRESULT, with only one possible success code (S_OK).
  • Each function is available in a corresponding character count (cch) or byte count (cb) version.
  • Most functions have an extended ("Ex") version available for advanced functionality."

Am Besten finde ich die ...Ex Funktionen, mit denen man beispielsweise in einer Schleife einen Buffer wie mit sprintf und einem Formatstring Stück für Stück befüllen kann und in jedem Schleifendurchlauf bekommt man mit [out]-Variablen das neue Stringende und die restliche Größe des Buffers zurück. Quasi sprintf on steroids!

Weil die Datei erst vor wenigen Jahren entstanden ist, ist sie natuerlich bei VC6 nicht mit in der Grundausstattung. Man muss ein halbwegs neues PlatSDK installiert haben und da ist die Datei dann dabei. Und natürlich gibt es alle Funktionen in ANSI, Unicode und character-set-agnostic Varianten.

<< 1 ... 37 38 39 40 41 42 43 44 45 46 47 >>