VS 2019 Debugger, Version 16.11.2, seltsames Verhalten "GetOutputTextExtent"



  • Hallo zusammen,
    hat jemand von Euch das auch schon erlebt? Oder bin ich der Einzige oder sogar verrückt?

    In meiner Software muss ich den Platzbedarf für einen Text in einer Tabelle ermitteln.
    Dafür verwende ich "pDC->GetOutputTextExtent(Text)".
    Seit ein paar Wochen wundere ich mich und war schon eine Woche verzweifelt am Suchen,
    weshalb die Tabelle öfters leer bleibt, obwohl Inhalt vorhanden ist.

    Nun habe ich herausbekommen, dass genannte Fktn recht astronomisch hohe Werte liefert.
    Also für "cx" und "cy" Werte von ca. 8164 oder 20987, oder 139665 oder ähnlich.
    Meist wird die Tabelle zunächst auch angezeigt, und es passiert dann beim Wechsel zu einer
    anderen Tabelle oder ist wieder weg, wenn man zu einer anderen Tabelle wechselt.
    Ich kann das nur im Debugger beobachten. Der Release-Build hatte das noch nie.
    Ich arbeite mit demselben Code auch noch unter VS 2005.
    Dessen Debugger läuft auch korrekt.



  • Die Funktion liefert die größe in LogicalUnits, die musst du ggf. zu Pixel konvertieren, das ist der Fall, wenn der Mapping Mode nicht MM_TEXT ist. Dazu gibt´s die Funktion CDC::LPtoDP, vielleicht funktioniert das? Hab´s natürlich nicht getestet.
    Ansonsten gibt´s auch noch die Funktionen GetTextExtentPoint32 und DrawText. Wenn man bei DrawText das Flag DT_CALCRECT setzt trägt es in den Parameter lprc die berechnete Größe des Texts ein.



  • @DocShoe Vielen Dank DocShoe für die Antwort.
    Ich hatte auch schon überlegt, ob das "font"-Objekt irgendwie beschädigt oder
    falsch initialisiert sein könnte. Das ist seit nun 8 Jahren noch nie gewesen.
    Und nun nur in diesem Debugger.
    Leider kann ich in das nicht reingucken (MS-Objekt Version irgendwas mit "mfc140.dll").
    Aber gut, ein paar Alternativen zu haben.
    ... Allerdings wird an einigen Stellen berichtet, dass das "GetOutputTextExtent"
    genau mit diesem "xxxPoin32" selbst arbeitet.
    Danke.



  • @DocShoe Evtl. ist es doch ein anderes Problem.
    Bitte um Entschuldigung!

    Nun ist es auch in den anderen Release-Versionen aufgetreten.
    Habe dort die Anzahl der Tabellen-Objekte auf gleiche Anzahl erhöht.

    Nur warum das passiert, weiss ich leider nicht. Hat doch der Font einen Schaden?
    Danke jedenfalls.



  • @elmut19
    Tja, was soll man dazu sagen? Meine Kristallkugel ist zu 100% mit der Lottozahlvorhersage beschäftigt, die will ich da nicht unterbrechen.
    Die erste Vermutung ist UB durch ungültige Speicherzugriffe, aber das musst du selbst rausfinden. cppcheck ist da schon mal ein guter Static Code Analyzer, ansonsten musste mal gucken, ob du nicht nen Profiler findest, der dir ungültige Speicherzugriffe meldet.



  • @elmut19 sagte in VS 2019 Debugger, Version 16.11.2, seltsames Verhalten "GetOutputTextExtent":

    Text

    Welchen Wert hat denn Text? Was steht drin? Vielleicht irgendwas ungültiges mit fehlendem Nullterminator?



  • Text ist vom Typ CString, fehlende Nullterminierung würde ich da eher ausschließen (klar, das zu überprüfen schadet natürlich nicht).
    Allerdings passt die Höhe überhaupt nicht, sodass ich wie @DocShoe davon ausgehen würde, dass Inhalte auf dem Stack überschrieben werden.
    Ich würde nicht davon ausgehen, dass die Schrift irgendwie beschädigt ist oder GetOutputTextExtent, das vermutlich auch nur GetTextExtentPoint32 aufruft, falsch arbeitet.



  • @wob Hallo wob,
    vielen Dank, dass Du trotz meiner ersten Fehlanalyse noch versuchst zu helfen.
    Gestern musste ich erstmal abbrechen

    Das Problem besteht natürlich noch immer und ist, da es unabhängig vom Debugger ist,
    auch noch schlimmer.

    Ich habe den Text natürlich angesehen. Der ist/war immer OK!
    Ich habe mir überlegt, ob es entweder der font sein kann, der evtl. nicht initialisiert ist.
    Aber der wird eigentlich initialisiert. Dann noch der Device Context, der vielleicht
    irgendwie ein anderes Device zugeordnet bekommen haben könnte.

    Ich weiss gerade nicht, wie ich das überprüfen kann, was da schief läuft.
    Und ich bin wirklich schon seit einer Woche permanent an diesem Problem, bis ich
    zu dem Stand gekommen bin, dass es an der berechneten Textlänge liegt, woraus sich
    ein Plausi-Fehler ergibt, um die Ausgabe abzubrechen. (Eine Länge von 8153 statt 28
    würde eh zu Mist führen)

    Man kann auch nicht sagen, wann die Aussetzer eintreten. Mal ist es beim ersten
    Aufruf der Tabelle, mal muss ich zehn mal zwischen mehreren Tabellen hin u her schalten.
    Und wenn ich wüsste, dass ich was mit dem Device Context in letzter Zeit gemacht hätte,
    hätte ich einen kleinen Anhaltspunkt.

    Also, wie prüfe ich am Besten, was mit dem Device Context nicht stimmt?
    Die Längen, die es bringt sind auch immer dieselben, als ob ein merkwürdiges
    Ausgabegerät initialisiert wurde.



  • Ich finde es faszinierend, dass du meine Vermutung mit UB und Codeanalyse durch Tools wie cppcheck und Memory Profiler einfach ignorierst. UB sind Fehler der übelsten Sorte und durch blosses Draufgucken meist nicht zu finden, es wird um so schwieriger, je größer das Projekt wird. Ich bin raus, ich wünsch dir noch viel Erfolg.



  • @DocShoe Danke Dir. Hatte Deinen Kommentar leider noch nicht gelesen.
    Werd ich aber nun machen (müssen). Dauert dann, bis ich mich eingearbeitet habe.
    Bin trotzdem für alle möglichen Ratschläge offen.

    ... Mein Device Context wird einfach der "OnDraw(pDC)" über geben.
    Aufgerufen wird die über irgendein Event, das im Hintergrund ausgelöst wird.
    Und ich weiss nicht wie (habe das Programm auch nicht geschrieben).
    Dieser "pDC" wird auch nirgends initialisiert. Bisher lief auch alles und immer.
    Mein "Textsearch" liefert zumindest weder Aufrufe von "OnDraw(..)" oder Eventzuordnungen, noch
    Initialisierungen des "pDC". Nur wenn ich drucken will schreibe ich explizit da was rein.

    Vielleich kann da ja was durcheinander kommen?



  • @elmut19
    Ich hatte wirklich über eine Woche verzweifelt gesucht.
    Bis ich dann bemerkt habe, dass in meiner (veralteten) INI-Datei ein nicht initialisierter Wert
    für einen Font drin stand. Ich schäme mich! Aber was tut man nicht aus Verzweiflung.
    Ich fühle mich nun doch gezwungen es hier aufzulösen.
    Danke für Eure Mühe



  • @elmut19 Ich würde dir empfehlen trotzdem zu schauen wieso da so komische Werte rauskommen, also die von dir erwähnten "8164 oder 20987, oder 139665 oder ähnlich". Das sollte auch nicht passieren trotz dem im .ini File kein Font eingetragen ist.

    Vermutlich prüft das Programm irgendwo den Returnwert nicht. Also ich könnte mir vorstellen dass es versuchst den Font zu erzeugen, was dann schief geht, und dann verwendest es das nicht initialisierte/ungültige Font-Handle trotzdem.

    Was dein OnDraw angeht: Das klingt sehr nach MFC. Da wird das vom Framework (also von der MFC) aufgerufen. Einen Zeiger auf einen passenden DC bekommt die Funktion ebenfalls vom Framework mitgegeben. Daher auch ganz normal dass du keinen Aufruf von OnDraw findest. Verdrahten muss man diese Funktionen auch nicht extra. Die Funktionen sind in der Basisklasse definiert, und es reicht dass man die überschreibt bzw. evtl. noch in der Message-Map einträgt (bei manchen Funktionen nötig, bei anderen nicht).



  • @hustbaer Vielen Dank Hustbaer.
    Ich habe dann schon genauer nachgesehen.
    Ein leerer Wert in der INI hätte im Programm eine "0" ergeben, also kein Problem.
    Aber da stand dann leider typischerweise "-87475926579" (oder ähnlich) drin.
    Das war schon saudooof. Und ich habe nicht bemerkt, dass die Korrekturen am INI
    nicht automatisch auch den Inhalt dessen korrigieren. Stehen auch ein Haufen Daten drin.


Anmelden zum Antworten