Programmieren


C++Windows 10Windows 8Martin Richter - Do 12 Okt 2017 12:40

Eigentlich habe ich nichts gegen Sicherheitsupdates. Genaugenommen bin ich ein Verfechter, dass Sicherheitsupdates sofort und umgehend installiert werden sollen.

Eigentlich ging das die letzten Jahre bei unserer Software ziemlich gut. Aber heute hat es uns voll erwischt. Dazu auf allen Plattformen von Windows 7, Windows 8.1 bis Windows 10.

Es kommt jetzt beim Anlegen einer Excel Datei über ODBC zu einer Fehlermeldung in der Form:

Reservierter Fehler (-5016); es gibt keine Meldung für diesen Fehler.
Ungültiges Attribut für die Verbindungszeichenfolge. CREATE_DB
Ungültiges Attribut für die Verbindungszeichenfolge. CREATE_DB
Ungültiges Attribut für die Verbindungszeichenfolge. CREATE_DB
Ungültiges Attribut für die Verbindungszeichenfolge. CREATE_DB
Allgemeine Warnung Registrierungsschlüssel ‚Temporary (volatile) Jet DSN for process 0x2c44 Thread 0x37f4 DBC 0x5b84d54 Excel‘ kann nicht geöffnet werden.
Ungültiges Attribut für die Verbin

Aktuell kann ich die Ursache nur in den folgenden Windows Updates sehen:

Windows 7 KB4041681
Windows 8.1 KB40416393
Windows 10 KB4040724
KB4041676

Einen entsprechenden Anfrage an andere Entwickler habe ich über Stackoverflow gestellt.

Als exMVP oder rMVP hat man jedoch nicht mehr die schönen Kanäle von früher… <seufz/> 🙁

Ich frage mich, wie solche Fehler durch eine Qualitätskontrolle schlüpfen können…?

ATLC++MFCProgrammierenVS 2015Windows 10Windows 10Martin Richter - Fr 24 Feb 2017 15:29

Wer es schnell mag, kann gleich den Beitrag und technische Details auf Stack Overflow lesen:
http://stackoverflow.com/questions/41741448/random-crashes-on-windows-10-64bit-with-atl-subclassing

Hier möchte ich etwas ausführlicher, die Story dazu erzählen, eine Story aus dem ganz „normalen“ Leben eines Programmierers 😉

Letztes Jahr stellen wir in der Firma produktiv von VC-2013 auf VC-2015 um. Wir haben eine relativ große Anwendung, die im Kern, MFC und ATL verwendet. Unsere Anwendung zeigt Informationen in vielen Tabs und Dialogen an. Mehr als 256 Fenster sind da keine Ausnahme und eher die Regel als eine Seltenheit.

Unsere Anwendung erzeugt bei Crashes automatisch volle Dumps auch bei Kunden. Für unsere Qualitätssicherung ein Muss und ein Segen.
Bereits in der Alpha und Beta Phase hatten wir auf manchen Rechnern ein eigentümliches Phänomen. Unser Programm startete und erzeugte Fenster und auf einmal kam es zu einem Absturz bei oft ganz einfachen Windows API Funktionen, die ein Fenster verwendeten und die alle ausnahmslos letzten Endes dazu führten, dass eine Nachricht an ein Fenster gesendet wird. Der Stack war nichtssagend und schien zerstört. Die Dumps für die einzelnen User waren aber fast immer glich.
Das Problem trat in Release und Debug Builds auf.

Der Horror für jeden Programmierer. Nicht nachzuvollziehende Crashes auf manchen Rechnern. Heapfehler? Wilder Zeiger? Buffer-Overrun? Nichts was man gebrauchen kann… aber kein Analysetool was wir verwendeten schlug Alarm…

Nach Sammlung von mehreren Dumps waren die Crashes immer wieder an ähnlichen Stellen und fast immer alle sofort nach Programmstart. Betroffen in der Regel alles Windows 10 64bit Maschinen auf dem aktuellen Softwarestand, meistens hatten diese Maschinen 8GB und zum Teil weitaus mehr Speichern und es waren ausnahmslos schnelle Intel i7 verschiedener Generationen. Und in virtuellen Maschinen konnte ich das bisher nicht nachvollziehen.

Interessant, war, dass ich diese Crashes auch auf meiner Entwicklungsmaschine hatte. Manchmal…
Nach einigen Tests konnte ich sagen. Entweder tritt der Fehler auf und solange der Rechner gestartet ist kann man es manchmal nachvollziehen, oder der Fehler tritt eben nicht auf und man hat Ruhe vor ihm. Dann hatte ich mir 3 Tage hintereinander – ohne Rechnerneustart – mit Debug-Session auf Debug-Session eine Spur erarbeitet. Es war immer das 257 Fenster, dass gesubclassed wurde (mit ATL Thunking) oder erzeugt wurde (ATL Fenster), dass zum Crash führte.
Insofern war es bei jedem User auch immer ein ähnlicher Dump, weil der Fensteraufbau ja bei jedem User individuell war.

Am Ende des dritten Tages hatte ich einen Testcode, der den Fehler in der aktuellen Windows Session meines Rechners und meinen Programm zu 100% nachvollziehbar machte. Ich verschob den Testcode immer weiter in einem Programm nach vorne, bis ich bei InitInstance ankam.
Ups. Es liegt nicht an meiner Software.
Dann isolierte ich den Testcode in eine eigenes Programm und konnte den Bug in einem minimalen Sample nachstellen.

Zeit für einen Support-Case bei Microsoft und eine Anfrage auf stackoverflow.com (das war am 19.01.2017).

Mit dem Case hatte ich natürlich auch einen Workaround. Ich musste nur einfach die atlthunk.dll nicht benutzen und auch das ging mit einer einfachen Änderung in der atlstdthunk.h. (Auskommentieren des defines USE_ATL_THUNK2).

Die Kommunikation mit Microsoft gestaltete sich nicht einfach. Aber ich hatte zumindest einen konstruktiven MS Mitarbeiter aus Indien erwischt. Dumps konnte ich Microsoft liefern, auch den Crash direkt in einer Session zeigen. Code hatten sie auch, aber der Bug war bisher nicht bei Ihnen nachvollziehbar. Das trieb mich fast in die Verzweiflung. Natürlich musste alles andere ausgeschlossen werden.. Virenscanner, andere Software… etc…
Dennoch kein Repro auf eine Microsoft Maschine. Allerdings weiß ich nicht wie „intensiv“ da gesucht wurde.

Dann endlich ein Lichtblick auf stackoverflow.com. Eugene konnte den Bug nachvollziehen. Endlich.
Und nachdem ich wusste, dass es mit der bevorzugten Ladeadresse zu tun hatte, konnte ich auch meinen Code erweitern und mit 100% Wahrscheinlichkeit den Crash erzeugen.
Wenn also an der bisher bevorzugten Ladeadresse der atlthunk.dll kein Speicher zur Verfügung liegt und sofort wieder eine Relocation notwendig wird, dann kracht es. Lustig, da wir ja durch ASLR sowieso keine festen Ladeadressen haben, aber es gibt innerhalb einer Windows Session dennoch eine „bevorzugte Ladeadresse“.

Jetzt bin ich gespannt auf Microsoft…
Denn defakto kann jede Software die mit dem VC-2015 und VC-2017 Compiler und der ATL kompiliert wurde von diesem Problem betroffen sein.

PS: Man entschuldige mir Ungenauigkeiten oder auch falsche Begrifflichkeiten…
Bis heute habe ich den Fehler immer noch nicht ganz verstanden und ganz sooo tief lebe ich im Kernel von Windows doch nicht. 😀

PPS: Ich werden den Artikel auf stackoverflow.com aktuell halten.

Nachtrag 01.03.2017:

  • Microsoft hat bestätigt, dass es sich um um einen Bug handelt.
  • Der Bug soll in der nächsten Windows 10 Version (RS2) gefixed sein.
  • Nachteil: Ich werde wohl mit der Änderung der ATL leben müssen, denn auch andere Windows Versionen sind von diesem Fehler betroffen.
InstallationProgrammierenSoftwareSonstigesMartin Richter - Fr 08 Jan 2016 16:23

Ihr seid vielleicht auch betroffen und nutzt bisher Code Signing für Eure Software oder MSI Pakete.
Ich zumindest habe von Symantec (ehemals Verisign) für unsere Zertifikate zum Jahresende eine Email bekommen, die mir empfiehlt zukünftig sowohl SHA1 als auch SHA256 zu nutzen. Entsprechende Links wurden mitgeliefert. (1) (2)(3)(4)

Ich habe also erstmal das bisherige Codesigning SHA1 Zertifikat als SHA256 Zertifikat neu ausgeben lassen. Das ganze war kostenlos über die Symantec Seite möglich und dauerte letzten Endes höchstens 30 Minuten.

Dann habe ich das neue Zertifikat im Produktionsserver installiert.
In unserem Produktionsprozess ist das Codesigning integriert. Die entsprechenden Dateien liegen in einem Quellordner und werden von unserem Produktionserver verwendet um daraus unsere Installationspakete oder Hotfixes zu generieren. Dabei werden alle Dateien entsprechend automatisch signiert.

Die entsprechende Code Passage in unserem Batch sah bisher so aus:

>signtool sign -sha1 FingerPint-SHA1-Zertifikat -fd sha1 -t http://timestamp.verisign.com/scripts/timstamp.dll myexe.exe

Da dachte ich: OK Ganz einfach, also nur eine zweite Zeile mit dem Parameter -as hinzufügen und das neue Zertifikat angeben.
Aber Pustekuchen:

>signtool sign -as -sha1 FingerPint-SHA256-Zertifikat -fd 256 -t http://timestamp.verisign.com/scripts/timstamp.dll myexe.exe
Done Adding Additional Store
SignTool Error: SignedCode::Sign returned error: 0x80070057
        Falscher Parameter.
SignTool Error: An error occurred while attempting to sign: AGVIP.exe

🙁 Nach einigem hin und her probieren und Lesen einiger Artikel, musste ich feststellen, dass die Ursache einzig und alleine in dem angegebenen Timestamp Server liegt. Der Verisign Timestamp Server mag einfach keine SHA256 Zertifikate für das Gegenzeichnen.

Die Lösung war also einfach. Ich habe einen anderen Timestamp Server benutzt und nun sehen die Befehlszeilen einfach so aus.

>signtool sign     -sha1 FingerPint-SHA1-Zertifikat   -fd sha1   -tr http://timestamp.geotrust.com -td sha1   myexe.exe
>signtool sign -as -sha1 FingerPint-SHA256-Zertifikat -fd sha256 -tr http://timestamp.geotrust.com -td sha256 myexe.exe

Und siehe da 🙂 alles funktioniert bestens und meine Programme haben nun 2 Zertifikate.

CommunityProgrammierenMartin Richter - Di 22 Sep 2015 20:34

Alles hat seine Zeit… (Prediger 3,1)

Eine kleine Ära geht für mich zu Ende. Vor kurzem erhielt ich von Microsoft die Information, dass ich dieses Jahr nicht neu zum C++ MVP nominiert werde.

Seit 2000 bis einschließlich 2014 habe ich diesen Titel insgesamt 16 mal erhalten. Über den Sinn und Zweck dieser Ehre mag man streiten. Stolz bin ich trotzdem drauf. Und gerade weil es mir mit anderen MVPs auch gelungen ist doch manchmal etwas Dampf und Druck zu machen. Z.B. damals für eine längere XP-Unterstützung, die wurde in VS-2012 Update 1 dann nachgeliefert. Obwohl ich klar sagen muss, dass die grundsätzliche Möglichkeit Einfluss zu nehmen in den letzten Jahren immer weiter abgenommen hat.

Hauptgrund ist sicherlich meine eingeschränkte Online Aktivität und auch meine nunmehr eingeschränkte Blog-Aktivität. Und um ehrlich zu sein: Ich hatte es irgendwann erwartet.

Meinen Blog werde ich deshalb nicht einstampfen und auch Online werde ich noch hier und da anzutreffen sein.
Also wird sich so viel für Euch gar nicht ändern… 😎

C++CRTProgrammierenVS 2015Windows APIMartin Richter - Fr 18 Sep 2015 16:15

Eine „Spaßbremse“ Software mit Visual Studio 2015 auszuliefern war bisher in jedem Fall das Universal CRT.

Im Speedproject.de Blog ist davon auch einiges zu lesen gewesen:
Noch kein Umstieg auf VS-2015
Anwendungslokaler Einsatz der Universal CRT
Visual Studio 2015 und die Universal CRT

Dieses Paket musste man zusätzlich mit installieren auf allen Systemen die Windows 7, Vista oder Windows 8.x verwendet haben. Die Probleme und das Nachfragen von Entwicklern hat nun Wirkung gezeigt.
Microsoft veröffentlicht den KB2999226 über Windows Update. Damit entfällt das Ausrollen mit dem eigenen Setup.

angeboten bzw. installiert wurde.

Danke für den Hinweis an Michael Külshammer. (siehe auch dotnetpro)

Nachtrag:
Bei mir erscheint jetzt auf meinen Windows 7 Rechner das entsprechende Update als optionales Update
KB2999226

ProgrammierenSoftwareTFSMartin Richter - Di 01 Sep 2015 20:04

Heute habe ich mir mal Zeit genommen ein Upgrade meines TFS-2013 auf TFS-2015 durchzuführen.
Mein Windows 2008R2 Server war mit SQL 2012 Server direkt bereit für das Update.

Summa summarum etwas mehr als 30 Minuten bis ich den folgenden Bildschirm hatte.

TFS-Upgrade3

Die Schritte waren:

  1. „Extra“ Backup des TFS
  2. Windows Update für virtuelle Maschine explizit noch mal ausführen.
  3. Snapshot der virtuellen Maschine ausführen.
  4. TFS-2015 Installation ausführen
  5. Beim automatischen Ausführen des Upgrade Wizards wurde erkannt, dass Powershell 3.0 nicht installiert ist. Sprich das Windows Management Framework 4.0 fehlte.
  6. Nach der Installation war leider ein Neustart fällig und der Upgrade Wizard wurde dadurch abgebrochen.
  7. Dann dauerte es leider etwas bis ich den Upgrade Wizard wieder „gefunden“ habe… 😉
    TFS Management Console starten -> Anwendungsebene auswählen -> Komponentenkonfiguration auswählen und im Konfigurationscenter dann Upgrade auswählen
  8. Abschließend die Reste des TFS und des alten Datei Caches aus „C:\Program Files\Microsoft Team Foundation Server 12.0“ entfernen.
  9. Done!

 

C++CommunityProgrammierenMartin Richter - Do 06 Aug 2015 22:50

Best Practices ist das nach dem wir oft suchen wenn neue Standards neue Methoden eröffnen und ganz besonders, wenn man sich mit einer Programmiersprache weiterentwickeln will.

Wir lesen Bücher von Scott Meyers, Bjarne Stroustrup, Nicolai Josuttis und nicht wenige von uns tummeln sich in Blogs studieren und nutzen fremden Code und Libraries. Alles das erweitert unseren „Programmierhorizont“.

Einige C++ Programmierer werden CppDepends kennen. Ein Tool von CodeGears, dass ich auch schon vorgestellt habe.
Die Firma hat eine neue Seite mit dem Titel C/C++ Coding Best Practices Repository . Die Idee ist „gute“ C++ Praktiken zu benennen, zu klassifizieren und zu bewerten. Und das macht in diesem Fall nicht ein Autor, sondern die Community. Wobei eben die Community die Regeln, die eingebracht werden bewerten und aus diesem Scoring könnten sich vielleicht ein paar wertvolle Bausteine heraus kristallisieren.

Solche Projekte können natürlich nur funktionieren, wenn genügend Leute mitmachen. Und da die Idee nicht schlecht ist mache ich hier mal etwas Werbung dafür.

 

C++ProgrammierenMartin Richter - Mo 20 Jul 2015 20:59

Heute haben zwei neue VisualStudio Versionen das Licht des RTM erblickt 😉

VisualStudio 2015 ist verfügbar und zeitgleich wurde auch VisualStudio 2013 Update 5 veröffentlicht.

Achtung: Wer als Sprache Deutsch angegeben hat, der bekommt aktuell (Stand 21.07.2015) noch die RC-Seite auf der deutschen Microsoft Seite angezeigt. Die englische Seite zeigt den RTM Artikel.

PS: Einzig vermisse ich noch die MBCS Bibliotheken für den RTM. Als RC waren sie verfügbar und der aktuelle Link auf den Microsoft Seiten funktioniert nicht. Auch wenn ich die nur für ein einziges Legacy Programm noch nutze.

C++CommunityProgrammierenVS 2015Martin Richter - Di 09 Jun 2015 18:59

Seit dem Erscheinen der ersten VC++ Express Version haben sich viele Entwickler gefragt, warum weder ATL noch MFC hier verfügbar waren.
Das hat sich nun seit der Existenz der VS-2013 Community Edition geändert.

Sowohl die Visual Studio 2013 Community Edition als auch die bereits veröffentlichte Visual Studio 2015 RC Community Edition enthält sowohl die ATL als auch die MFC. D.h. auch, dass es damit einfacher wird für nicht kommerzielle Entwickler die entsprechenden Libraries zu verwenden.

Das ist auch endlich ein Durchbruch, der von der MVP-Community seit dem erscheinen der aller ersten Express Version angemahnt und gefordert wurde.

Die aktuellen Downloads finden sich hier:
http://www.visualstudio.com/de-de/downloads/download-visual-studio-vs.aspx
http://www.visualstudio.com/en-us/products/vs-2015-product-editions.aspx

Bei der Installation der VS-2015 Community Edition muss man allerdings darauf achten die MFC mit auszuwählen. In der Standardinstallation wird diese nicht hinzugefügt. In der VS-2013 Version wird die MFC automatisch mit installiert.

Nur zur Info:
Die Community Edition ersetzt in Zukunft die Express Versionen. Zudem werden alle Express Editionen in einem Visual Studio Paket zusammen geschnürt. Der Vorteil ist groß. Addons werden verfügbar, für die breite Maße. Opensource Projekte, die die MFC und ATL verwenden stehen nun jedermann zur Verfügung. Weitere Infos finden sich auch hier.
Die Lizenzbedingungen der Commuinity Edition sollte man unbedingt lesen, wenn man die Version auch kommerziell nutzen möchte.

PS: Diese Pakete existieren bereits seit November 2014 aber mir ist diese Info bisher entgangen. Sorry…

C++ProgrammierenVS 2015Martin Richter - Mo 04 Mai 2015 17:25

Seit den letzten Tagen des April ist nun auch der Release Candidate für VS_2015 verfügbar.
http://www.visualstudio.com/en-us/news/vs2015-vs.aspx

Die Liste ist lang. Was sich für C++ Neues ergibt dagegen doch recht übersichtlich. 😉

Hier ein paar Punkte, die ein erster Test und Streifzug ergab:

  • Man sollte in jedem Fall die angepasste Installation verwenden. Ansonsten wird der MFC Sourcecode nicht mit installiert (siehe auch Kommentar von Michael Külshammer)
  • „Fast“ alle Projekte ließen sich fehlerfrei kompilieren. Es gab zwar einen Haufen neuer Warnungen aber, diese haben eher mit dem Stil des Programmierens zu tun. Speziell sind es C4456, C4457, C4458 (Declaration off… hides previous …  declaration). Im Klartext. Ich verwende immer mal wieder eine Variable it oder i gerne, die auch im äußeren Scope vorhanden ist.
    Für diese neuen Warnings gibt es allerdings bisher keine Dokumentation.
  • Und eben die typischen Fallen in denen man eben thirdparty Libs (z.B. OpenSSL) eben neu erzeugen muss.
  • Leider benötige ich für ein spezielles Update Programm noch die MBCS Variante der MFC. Diese ist zwar über das Netz als Link bei MS vorhanden, führt aber zu einer 404 Sackgasse. (Dieses Programm benutzt extrem alten Code, bei denen noch niemand an char/wchar_t bzgl. der Windows API und anderes dachte und Neuschreiben hatte ich bisher vermieden. 🙂 )
  • Nervig war eine „neue“ Compilermeldungen C1041, aber diese ist nirgendwo beschrieben (wie auch andere nicht). Online jedenfalls nicht. Ich bekam den Hinweis, dass eine PDB Datei nicht geschrieben werden kann und ich bitte die Option /FS verwenden soll. Die Ursache ist mir unklar, weil bei späteren Kompilierungsversuchen das Ganze durchlief.
  • Etwas länger musste ich für den folgenden Fehler suchen:
     (odbccp32.lib(dllload.obj) : error LNK2019: unresolved external symbol _vsnwprintf_s referenced in function StringCchPrintfW).
    Hier scheint noch etwas mit dem SDK auch in der Release Version nicht zu passen. Auf connect.microsoft.com fand ich einen entsprechenden Eintrag um diesen Fehler zu umgehen. Scheinbar ist das neue „korrigierte“ SDK, dass in der Lösung versprochen wird im RC noch nicht enthalten.
  • Vieles in der UI hat sich geändert. So werden zum Beispiel die Breakpoint mit einem eigenen Kontexttoolbar angezeigt und benutzt man diesen dann werden die Einstellungen nicht in einem Dialog angepasst, sondern innerhalb des Sourcecode Fensters wird am unteren Rand ein Box für die Eigenschaften geöffnet. Das ist definitiv gewöhnungsbedürftig. Und nur mit der Maus zu bedienen.
  • Im MFC Sourcecode findet sich nur eine neue Header-Datei afxlayout.h. In dieser Headerdatei findet sich die Deklaration für die Klasse CMFCDynamicLayout. Diese Klasse wird direkt in CWnd als Zeiger verwendet und erlaubt die Neupositionierung von Kindfenstern damit für alle Fenstertypen. D.h. nicht nur Dialoge. D.h. man kann in jedem MFC-Fenster EnableDynamicLayout ausführen und entsprechend die Kindfenster neu anordnen lasen wie man es selber definiert.
    Die Implementierung schließt scheinbar die Nutzung des Ressourceneditors ein, denn die Einstellungen können aus dem Ressourcentyp RT_DIALOG_LAYOUT ausgelesen werden. In den Fenstereigenschaften eines Controls findet sich nun der Abschnitt Dynamic Layout in dem man Position und Größe in Prozent zur Gesamtänderung angeben kann.
  • Wer die Header genauer untersucht findet klitze kleine Änderungen Hier und Da wie z.B. die Unterstützung von runden Ecken bei Tooltipps.
  • In der ATL konnte ich bisher keine Erweiterungen und gravierende Änderungen finden.
  • Die meisten Änderungen im ATL und MFC sind Änderungen im Trace Code. Statt „%s“ wird nun konsequent „%Ts“ als Formatierungszeichen verwendet. Angekündigt war eine grundsätzliche Änderung bzgl. „Wide String Format Specifiers“ allerdings wurde diese bereits im April zurückgezogen (siehe hier).
  • Vermisst habe ich einige CRT Source Dateien, die normalerweise im VC\CRT\SRC Order liegen. Der Ordner war in meiner Installation leer und enthielt nur weitere Ordner.
    Mir war es auch nicht möglich beim Testen in den CRT Code zu steppen. Zumindest bei mir wurden keine passenden Source Dateien gefunden.
  • Mit den CRT-DLLs werde ich mich ab morgen mal befassen. Auch hier hat Michael Külshammer gerade eben einen Beitrag in meinem Blog geschrieben.

Summa summarum nur minimale Anpassungen in meinen Projekten für den Umstieg von VS-2013 auf VS-2015, darüber hinaus so gut wie keine (erkennbaren) Änderungen in der CRT/ALT und MFC. Was es an neuen Compiler Features gibt findet man in den Blogs ausführlicher beschrieben als ich das kann. Zudem halte ich mich nicht für den großen C++ Sprachen-und-Standard-Guru.

 

Nächste Seite »