VC++ 6.0 debuggen



  • @gjk sagte in VC++ 6.0 debuggen:

    Ich verstehe nur nicht:
    -> Prog lässt sich in Debug kompilieren
    -> F5 und hält dann auch an Breakpoint an
    -> jetzt mit F10 weiter ---> gibt Access violation!
    was meinst du genau soll ich noch beachten?

    Die Vorgehensweise ist recht einfach. Du musst nachschauen welche Funktion du an der Stelle aufrufst, welche Parameter du der Funktion (siehe Debugger) übergibst und welche Parameter die Funktion wünscht (Doku).

    Ein Klassiker bezüglich Access Violation ist beispielsweise ein nicht initialisierter Pointer.



  • @Quiche-Lorraine

    Oder ein falsches Speicherlayout. Das kann viele Gründe haben.



  • @DocShoe Moin. Das mit der Funktion habe ich ja verstanden und das kann ich ausschließen. Es geht auch nicht, dass ich mit F10 z.B. in einer Schleife cruisen kann. Was ist gemeint mit Speicherlayout oder nach was kann ich da googeln?



  • @gjk
    Am Besten du postest mal den Abschnitt des Quellcodes mit dem Funktionsaufruf.

    Manchmal unterscheiden sich Strukturen/Klassen in Debug- und Release-Version, weil zB im Debug Modus zusätzliche Member mit Debug-Informationen existieren. Wenn man beim Bauen dann zwar die Debug-Header verwendet aber gegen die Release-Bibliotheken linkt stimmen die Offsets für die Member nicht und man erhält einen Speicherzugriffsfehler.

    Das kann ein Grund für deinen Fehler sein.



  • Du gibst dir echt Mühe mit mir. Danke!
    Hier ein Ausschnitt. Ich stehe -> und will mit F10 weiter debuggen.:
    void CEdiNrPrintDlg::EdiDateienZeigen(int jahr, int monat)
    {
    CString Pfad;
    SetzeEdiPfad();
    CFileFind cff;
    BOOL bGefunden;
    CString Dateiname;
    //in 2-stellige Angabe umwandeln
    jahr = jahr % 100;
    m_DatDir.Format("%s%02d%02d\Data",m_EdiDir,jahr,monat);
    m_lstNummern.ResetContent();
    m_bnDrucken.EnableWindow(FALSE);
    m_bnELSDrucken.EnableWindow(FALSE);
    m_bnEtikett.EnableWindow(FALSE);

    m_lstDateien.ResetContent();
    Pfad.Format("%s%02d%02d\\Data\\*ABRP.dat",m_EdiDir,jahr,monat);
    

    -> bGefunden = cff.FindFile(Pfad);
    while( bGefunden) {
    bGefunden = cff.FindNextFile();
    Dateiname = cff.GetFileName();
    m_lstDateien.AddString(Dateiname);
    }

    }
    Dann kommt ERROR



  • @gjk sagte in VC++ 6.0 debuggen:

    while( bGefunden) {
    bGefunden = cff.FindNextFile();
    Dateiname = cff.GetFileName();
    m_lstDateien.AddString(Dateiname);
    }

    Das sieht doch sehr verdächtig aus. Egal ob eine Datei gefunden wurde oder nicht, du liest ihren Dateinamen aus. Die Zeile bGefunden = cff.FindNextFile(); gehört nach unten in die Schleife.

    Edit: ich nehme dies zurück, nachdem ich in die Doku geschaut habe. Das scheint so richtig zu sein, wie du es gemacht hast. Finde ich sehr kontraintuitiv. Aber ich arbeite auch nicht mit dem CFindFile. Hätte es dennoch anders erwartet.



  • Wie sieht denn der Inhalt von Pfad zum Zeitpunkt des Aufrufs aus, ist das ein gültiger Pfad?
    Bei der Formatierung von m_DatDir fehlt jedenfalls ein Bäcksläsch, nicht dass Windows/MFC über einen ungültigen Pfadnamen stolpert.

    PS:
    Bitte den Code über Code-Tags formatieren



  • @wob Es funktioniert soweit ja auch alles; es ist auch nur exemplarischer Code. Das Problem des debuggens taucht überall auf.
    Ich will/muss nur ein paar Parameter ändern; dazu will ich die Reihenfolge der Aufrufe betrachten.



  • @gjk sagte in VC++ 6.0 debuggen:

    @wob Es funktioniert soweit ja auch alles; es ist auch nur exemplarischer Code. Das Problem des debuggens taucht überall auf.
    Ich will/muss nur ein paar Parameter ändern; dazu will ich die Reihenfolge der Aufrufe betrachten.

    Ich habs auch schon zurückgenommen. Ich kenne die FindFirst/FindNext noch von Turbo Pascal... Dort und auch in der WinAPI FindFirstFileW wäre das, was ich geschrieben hatte, richtig gewesen.



  • @wob sagte in VC++ 6.0 debuggen:

    while( bGefunden) {
    bGefunden = cff.FindNextFile();
    Dateiname = cff.GetFileName();
    m_lstDateien.AddString(Dateiname);
    }

    Wäre es da nicht besser dies folgendermaßen zu erledigen?

    void CEdiNrPrintDlg::EdiDateienZeigen(int jahr, int monat)
    {
      CString Pfad;
      SetzeEdiPfad();
      CFileFind cff;
      BOOL bGefunden;
      CString Dateiname;
      //in 2-stellige Angabe umwandeln
      jahr = jahr % 100;
      m_DatDir.Format("%s%02d%02d\Data",m_EdiDir,jahr,monat);
      m_lstNummern.ResetContent();
      m_bnDrucken.EnableWindow(FALSE);
      m_bnELSDrucken.EnableWindow(FALSE);
      m_bnEtikett.EnableWindow(FALSE);
    
      m_lstDateien.ResetContent();
      Pfad.Format("%s%02d%02d\\Data\\*ABRP.dat",m_EdiDir,jahr,monat);
     bGefunden = cff.FindFile(Pfad);
     while(cff.FindNextFile()) {  
       Dateiname = cff.GetFileName();
       m_lstDateien.AddString(Dateiname);
     }
    }
    

    Ich traue der Funktion cff.GetFileName() nicht so recht, wenn cff.FindNextFile() false zurückliefert.



  • @Quiche-Lorraine sagte in VC++ 6.0 debuggen:

    Ich traue der Funktion cff.GetFileName() nicht so recht, wenn cff.FindNextFile() false zurückliefert.

    Ist aber richtig laut Doku. Siehe Beispiel hier: https://docs.microsoft.com/de-de/cpp/mfc/reference/cfilefind-class?view=msvc-170

    Laut https://docs.microsoft.com/de-de/cpp/mfc/reference/cfilefind-class?view=msvc-170#findnextfile returnt das 0 bei Fehler oder wenn die letzte Datei gefunden wurde. Wer denkt sich sowas aus?! Man muss also eigentlich immer GetLastError aufrufen.

    Wie gesagt, war auch kontraintuitiv für mich, aber damit scheine ich den Thread in die falsche Richtung gelenkt zu haben. Sorry!

    Was mir nur unklar ist, wie funktioniert dies praktisch, wenn 0 Dateien gefunden werden? Vielleicht ist das auch das Problem?

    Ungleich 0 (null), wenn weitere Dateien vorhanden sind. 0 (null), wenn es sich bei der gefundenen Datei um die letzte Datei im Verzeichnis handelt oder wenn ein Fehler aufgetreten ist. Um erweiterte Fehlerinformationen abzurufen, rufen Sie die Win32-Funktion GetLastErrorauf. Wenn die gefundene Datei die letzte Datei im Verzeichnis ist oder keine übereinstimmenden Dateien gefunden werden können, gibt die GetLastError Funktion zurück ERROR_NO_MORE_FILES.

    Wie unterscheide ich "letzte Datei" von "es gibt gar keine Datei"?!



  • Dann sollte das so aussehen?

    void CEdiNrPrintDlg::EdiDateienZeigen(int jahr, int monat)
    {
       CString Pfad;
       Pfad.Format("%s%02d%02d\\Data\\*ABRP.dat",m_EdiDir,jahr,monat);
       if( cff.FindFile( Pfad ) )
       {
          while( cff.FindNextFile() )
          {
             ...
          }
       }
    }
    


  • @DocShoe sagte in VC++ 6.0 debuggen:

    Dann sollte das so aussehen?

    Nein, weil 0 der Rückgabewert bei der letzten Datei ist. Rückgabe ist "0 (null), wenn es sich bei der gefundenen Datei um die letzte Datei im Verzeichnis handelt " - das sollte also eine Datei zu wenig zurückliefern (ich habe kein Windows hier, müsste mal jemand mit Win testen).



  • @DocShoe sagte in VC++ 6.0 debuggen:

    Dann sollte das so aussehen?

    Laut einem Beispiel aus der Doku (https://docs.microsoft.com/de-de/cpp/mfc/reference/cfilefind-class?view=msvc-170#isdirectory) sollte es so aussehen:

    void CEdiNrPrintDlg::EdiDateienZeigen(int jahr, int monat)
    {
       CString Pfad;
       Pfad.Format("%s%02d%02d\\Data\\*ABRP.dat",m_EdiDir,jahr,monat);
       BOOL bWorking = cff.FindFile( Pfad );
       while ( bWorking )
       {
          bWorking = cff.FindNextFile();
          ...
       }
    }
    


  • Jo, hab den Abschnitt in der MFC Doku inzwischen auch gelesen. Möchte mal wissen, ob der Programmierer sich damals stolz auf die Schulter geklopft hat.



  • @DocShoe sagte in VC++ 6.0 debuggen:

    o, hab den Abschnitt in der MFC Doku inzwischen auch gelesen. Möchte mal wissen, ob der Programmierer sich damals stolz auf die Schulter geklopft hat.

    Leider tauchen solche Tücken öfters in der WinAPI auf.

    @gjk

    Es funktioniert soweit ja auch alles; es ist auch nur exemplarischer Code. Das Problem des debuggens taucht überall auf.

    Taucht das Problem auch bei kleineren Test-Programmen auf? Setz doch mal ein Test-Projekt auf und probiere ob dort das debuggen funktioniert.



  • VC6 auf aktuellen Windows Versionen zum Laufen zu bekommen ist nicht ohne. Ich könnte mir auch vorstellen dass es Probleme gibt wenn man die Programme debuggen möchte.

    Also: welche Windows Version verwendest du? Vielleicht wäre eine Möglichkeit Windows XP in einer VM zu installieren und da drinnen dann VC6.


Log in to reply