Programm stürzt im Release Modus ab



  • Guten Abend Gemeinde,

    Ich habe ein Programm welches die aktuellen Möglichkeiten der MFC bzgl. andockbarer Fenster nutzt.
    Ich habe die Tage ein Fenster ergänzt seit dem stürzt das Programm in der Release Version ab. Dies geschieht aber nicht wenn das Programm (auch ohne Debuginformationen) im Debugger (der mault zwar wegen der fehlenden Info, startet das Programm aber) gestartet wird.
    Das Fenster soll in der CMainFrame::OnCreate erzeugt werden. Ich konnte soweit eingrenzen, dass das Programm in der CPigPane::OnCreate an der CreateEx abstürzt, wenn ich die Auskommentiere läuft der Rest (der Restliche Code für m_wndLogPigPos wurde zur Fehlersuche schon auskommentiert).

    Habt Ihr eine Idee wie ich den Fehler beheben kann, ich bin im Moment doch recht ratlos.

    #pragma once
    
    #include "afxcmn.h"
    //#include <deque>
    //#include "Pig.h"
    
    class CPigPane : public CDockablePane
    {
      // Konstruktion
    public:
      CPigPane(){}
    
      void UpdateFonts(CFont* fnt)
      {
        m_wndList.SetFont(fnt);
      }
    
      void UpdateData();
    
      // Attribute
    private:
    
      CListCtrl m_wndList;
    
    public:
      ~CPigPane(){}
    
    protected:
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      afx_msg void OnSize(UINT nType, int cx, int cy);
    
      DECLARE_MESSAGE_MAP()
    
    private:
    };
    
    #include "stdafx.h"
    #include "APMS_Client.h"
    #include "PigPane.h"
    
    #include <iostream>
    
    BEGIN_MESSAGE_MAP(CPigPane, CDockablePane)
      ON_WM_CREATE()
      ON_WM_SIZE()
    END_MESSAGE_MAP()
    
    int CPigPane::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
      if (CDockablePane::OnCreate(lpCreateStruct) == -1)
        return -1;
    
      CRect rectDummy(0,0,10,10);
      //rectDummy.SetRectEmpty();
    
      // Registerkartenfenster erstellen:
      if (!m_wndList.CreateEx(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_AUTOSIZECOLUMNS,
        LVS_REPORT | LVS_ALIGNLEFT | LVS_NOSORTHEADER |
        WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL,
        rectDummy, this, 27))
      {
        TRACE0("Fehler beim Erstellen des Ausgaberegisterkarten-Fensters.\n");
        return -1;      // Fehler beim Erstellen
      }
      m_wndList.InsertColumn(0, L"Typ",              LVCFMT_LEFT, 200);
      m_wndList.InsertColumn(1, L"Zähler (Start)",   LVCFMT_LEFT, 150, 1);
      m_wndList.InsertColumn(2, L"Position",         LVCFMT_LEFT, 100, 2);
      m_wndList.InsertColumn(3, L"Schlupf",          LVCFMT_LEFT, 100, 3);
      m_wndList.InsertColumn(4, L"letzte Korrektur", LVCFMT_LEFT, 200, 4);
      m_wndList.InsertColumn(5, L"Ankunft",          LVCFMT_LEFT, 300, 5);
    
      UpdateFonts(&theApp.m_fntMono);
    
      return 0;
    }
    
    bNameValid = strCaption.LoadString(IDS_WND_LOG_PIGPOS);
        ASSERT(bNameValid);
        if (!m_wndLogPigPos.Create(strCaption, this, CRect(0, 0, 100, 100), TRUE, ID_VIEW_LOG_PIGPOS, dwStyle | CBRS_BOTTOM))
        {
          TRACE0("Fehler beim Erstellen des Fensters ID_WND_LOG_PIGPOS");
          return FALSE;
        }
    

  • Mod

    Attache den Debugger nachträglich.

    Wenn der Debugger mitläuft wird auch der Debug-Heap verwendet.
    Wenn Du also einen Heap-Fehler verursachst dann ist solch unterschiedliches Verhalten möglich.

    In der Release Version werden ja auch Variablen nicht initialisiert. Auch das kann ein Fehler sein.



  • Martin Richter schrieb:

    In der Release Version werden ja auch Variablen nicht initialisiert. Auch das kann ein Fehler sein.

    Darauf läuft es meistens raus wenn's im Debug-modus läuft und in Release nicht.



  • Du könntest Versuchen dem Problem mit einem Tool wie Valgrind bzw. Dr. Memory nachzuspüren.

    Damit werden z.B. Zugriffe auf nicht-initialisierte Variablen, Zugriffe auf hängende Zeiger, Pufferüberläufe, Memory-Leaks und ähnliche Programmierfehler angezeigt...



  • Martin Richter schrieb:

    Attache den Debugger nachträglich.

    Wenn der Debugger mitläuft wird auch der Debug-Heap verwendet.
    Wenn Du also einen Heap-Fehler verursachst dann ist solch unterschiedliches Verhalten möglich.

    Das wird nicht funktionieren, da das Programm ja schon bei der CMainFrame::OnCreate stirbt. Oder ich verstehe gerade nicht was ich machen soll.
    Aber Du stellst auf den Heap ab. Könnte mir das hier von Microsoft irgend wie helfen?

    Martin Richter schrieb:

    In der Release Version werden ja auch Variablen nicht initialisiert. Auch das kann ein Fehler sein.

    Das vermute ich ja auch, nur wie finden? Häßlicher Fehler. Ich habe zwar so gut wie keine rohen Zeiger aber würde /W4 oder /Wall bzgl. der nicht initialisierten Variablen was bringen?

    DeathCubeK schrieb:

    Du könntest Versuchen dem Problem mit einem Tool wie Valgrind bzw. Dr. Memory nachzuspüren.

    Damit werden z.B. Zugriffe auf nicht-initialisierte Variablen, Zugriffe auf hängende Zeiger, Pufferüberläufe, Memory-Leaks und ähnliche Programmierfehler angezeigt...

    Danke für den Tip, kann ich aber leider nicht machen. Ich bewege mich in einer geschlossenen Umgebung wo ich nichts (schon gar nichts Ausführbares) reinbringen darf. Das wäre zumindest mit erheblichem Aufwand verbunden.



  • kauf deinem chefchen ein buch



  • andreasgeorg schrieb:

    DeathCubeK schrieb:

    Du könntest Versuchen dem Problem mit einem Tool wie Valgrind bzw. Dr. Memory nachzuspüren.

    Damit werden z.B. Zugriffe auf nicht-initialisierte Variablen, Zugriffe auf hängende Zeiger, Pufferüberläufe, Memory-Leaks und ähnliche Programmierfehler angezeigt...

    Danke für den Tip, kann ich aber leider nicht machen. Ich bewege mich in einer geschlossenen Umgebung wo ich nichts (schon gar nichts Ausführbares) reinbringen darf. Das wäre zumindest mit erheblichem Aufwand verbunden.

    Bei Speicher-Fehlern muss die Stelle, an der es letztendlich kracht, nicht unbedingt etwas mit dem eigentlichen Problem zu tun haben. Wenn Du Dir z.B. irgendwo durch einen Puffer-Überlauf irgendwelche "benachbarten" Daten kaputt schreibst, kracht es mitunter erst viel später und an einer ganz anderen Stell, wenn Du wieder mal auf diese Daten zugreifst. So etwas ohne geeignete Werkzeuge aufzuspüren ist die sprichwörtliche Suche nach der Nadel im Heuhaufen. Erst recht, wenn der Code einigermaßen komplex ist. Ja nach dem wie viel Zeit Du schon mit der Suche verbraten hast, würde ich mir gut überlegen, ob Du nicht vllt doch irgendwie einen Memory-Debugger in deine "geschlossenen Umgebung" hinein bekommst. Ist am Ende möglicherweise der geringere Aufwand...


  • Mod

    Schau mal was an der Stelle steht, die dort ausgelkesen oder verwendet wird.
    Oft genug ist es ein String oder ähnliches un man kann sehen, was den Speicher überschrieben hat.

    Zudem verwende mal aggressive Techniken die den Heap prüfen.

    Ich habe dazu mal ein paar Tipps zusammengeschrieben:
    http://blog.m-ri.de/index.php/2008/10/27/vs-tipps-tricks-heap-bugs-finden-teil-1/
    http://blog.m-ri.de/index.php/2008/10/31/vs-tipps-tricks-heap-bugs-finden-teil-2/
    http://blog.m-ri.de/index.php/2008/11/04/vs-tipps-tricks-heap-bugs-finden-teil-3/



  • Danke Euch Allen,

    die Links sind sehr lehrreich, wenn auch ich keine Speicherverletzung finden konnte.
    Am Ende habe ich das Programm immer weiter reduziert, bis eigentlich kein Nutzcode mehr enthalten war. In dem MFC Programmgerippe habe ich den zuletzt den Standard Code für die angepassten Menüs und für die ToolTips entfernt (beides ist in meiner Anwendung ohnehin nicht nötig/sinnvoll) und seit dem läuft das Programm ohne Probleme wie es soll als Debug und Release Version mit und ohne Debugger.

    Eins noch, ich habe nochmal die Compiler und Linker Einstellungen mit denen eines frische Projekts verglichen und ein zwei Einstellungen korrigiert.

    Final ist der Code jetzt ca. 100 Zeilen länger. Das sind dann eine ganze Reihe ASSERTs die dazu gekommen sind um weitere Probleme zu vermeiden.


Log in to reply