Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hi!

Ich habe das Problem, das mein Programm im Debug-Modus ohne Fehler läuft

aber wenn ich es als Release erstelle stüzt es ab.

Es kommt der Fehler:

Die Anweisung in "0x73d311x7" verweiß auf den Speicher in "0x00000139".

Der Vorgang "read" konnte auf dem Speicher nicht ausgeführt werden.

Wie kann ich denn rausfinden wo der Fehler liegt wenn es im Debug-Modus ganz normal läuft? Hab schon bereinigt und neu erstellt...

Woran kann das liegen?

Gruß

Filou

Geschrieben

Habe jetzt rausgefunden dass es wohl an

pWnd->PostMessage(WM_CHECKTERMINE, 0, 0);

liegt. Das wird in einem Thread gemacht.

Wenn ich es auskommentiere gehts auch als Release

Aber wieso läuft es unter Debug?

Und was kann daran falsch sein?

Geschrieben

Probleme im Release, die im Debug nicht auftreten, haben meist eine der folgenden Ursachen:

- uninitialisierte Variablen

- Arraybereichsüberschreitungen

- mangelnde Synchronisation

In der Debugversion werden Variablen automatisch mit bestimmten Werten initialisiert. Außerdem wird rund um dynamisch angelegten Speicher ein Pufferbereich angelegt, so dass Bereichsüberschreitungen nicht gleich andere Variablen überschreiten. Und natürlich ist bei Release durch die Optimierung das Zeitverhalten, gerade bei mehreren Threads anders. Wenn man da nicht ordentlich synchronisiert hat, knallt's eben.

Geschrieben

Ich habe nen Haltepunkt in die Funktion gemacht die durch WM_CHECKTERMINE aufgerufen wird. Ganz oben.

Aber das programm sürtzt vorher ab.

Also kanns doch nicht an einer Variable liegen, die ich angelegt habe, oder?? :confused:

PS:

Der fehler passiert in der MFC42.DLL

Aufrufliste: MFC42! 73d311c7()

Register:

EAX = 00000111 EBX = 77D1D7F9

ECX = 00000135 EDX = 0033E7C8

ESI = 0012F35C EDI = 0012F35C

EIP = 73D311C7 ESP = 0012C67C

EBP = 0044AEA4 EFL = 00000206

Geschrieben
Also kanns doch nicht an einer Variable liegen, die ich angelegt habe, oder?? :confused:
Welchen Wert hat pWnd denn an dieser Stelle? Die Fehlermeldung könnte auf einen Nullzeiger hinweisen.

Aufrufliste: MFC42! 73d311c7()
Ist das wirklich die ganze Aufrufliste?
Geschrieben

Wenn ich das Problem richtig verstanden habe dann versuchst du aus einem Thread über eine Zeigervariable eines Fenster eine Nachricht an einen anderen Thread zu schicken.

Hat der Thread der die Nachricht abschickt das Fenster erstellt? Du kannst keine MFC Objekte über Threadgrenzen hinweg durchreichen. Was du machen kannst ist den Window Handle übergeben und die normale API Funktion

::SendMessage(HWND,UINT,WPARAM,LPARAM) verwenden.

Geschrieben
Wenn ich das Problem richtig verstanden habe dann versuchst du aus einem Thread über eine Zeigervariable eines Fenster eine Nachricht an einen anderen Thread zu schicken.

Hat der Thread der die Nachricht abschickt das Fenster erstellt? Du kannst keine MFC Objekte über Threadgrenzen hinweg durchreichen. Was du machen kannst ist den Window Handle übergeben und die normale API Funktion

::SendMessage(HWND,UINT,WPARAM,LPARAM) verwenden.

Danke für den Tip. Ich bin nicht sicher ob ichs richtig gemacht habe.

Also ursprünglich hatte ich es so:

pWnd->PostMessage(WM_CHECKTERMINE, 0, 0);
Da ging der Dialog auf und das Programm ist beim schließen des Dialogs abgesürzt. (Die Nachricht soll eine Funktion starten die einen Dilaog modal öffnet) Jetzt habe ichs so versucht:
pWnd->SendMessage(WM_CHECKTERMINE,0,0);
Da stützt das Programm gleich ab. Und so habe ichs auch versucht:
SendMessage(HWND_BROADCAST,WM_CHECKTERMINE,0,0);

Da passiert aber garnix.

Das alles hier steht in dem Thread.

Geschrieben
Welchen Wert hat pWnd denn an dieser Stelle? Die Fehlermeldung könnte auf einen Nullzeiger hinweisen.

Ist das wirklich die ganze Aufrufliste?

Ja das war die ganze Aufrufliste.

pWnd kann ich an der Stelle wos knallt nicht mehr sehen.

Geschrieben

Probier mal

PostThreadMessage(DWORD idThread,UINT Msg,WPARAM wParam,LPARAM lParam);

Die Frage ist jetzt nur noch, ob du deinen pWnd Zeiger auch in dem Thread erzeugst oder im Hauptapplikationsthread.

Wie sieht deine Threadfunktion aus? Was übergibst du ihr als Parameter?

Geschrieben

Das geht auch nicht (es passiert garnix):

PostThreadMessage(0,WM_CHECKTERMINE,0,0);

Wobei ich nicht weiß ob das richtig ist wenn ich immer nur 0 angebe.

Ich habe ja keine Zielthread für die Nachricht.

Das Ziel ist eine Memberfunktion in der Klasse meines Dialogs bzw die Message Map die dann die Memberfunktion starten soll.

Es lässt sich kompilieren, stürtzt dann aber auch ab.

Vielleicht liegt es an etwas ganz anderem??

Ich will einfach nur diese Funktion starten die einen Dialog öffnet :(

Das einzige was bis jetzt die Funktion gestartet hatte war PostMessage.

Es ist halt nur nach dem schließen des Dialogs, der durch die Funktion geöffnet wurde, abgestürzt.

Geschrieben

Danke, dass Du mir hilfst!!

Also hier ist mal ein bissel Code.



BEGIN_MESSAGE_MAP(CPatient, CDialog)

	//{{AFX_MSG_MAP(CPatient)

	ON_MESSAGE(WM_CHECKTERMINE, OnCheckTermine)

	//}}AFX_MSG_MAP

END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////

// Therad definieren


//BOOL m_bThreadEnd;

UINT DBUeberwachung(void* pParam)

{

	CPatient *pWnd;

	pWnd=(CPatient*)pParam;

	int iCounter = 0;


	//Dieser Thread überprüft alle 30 Sekunden die Verbindung zur Datenbank 

	//und aktuallisiert die die Anzeige.

	while (g_iDBUeberwachung != 5555) //ENDLOS

		{

		//DATENBANKÜBERWACHUNG AKTIV

		if(g_iDBUeberwachung == SERVICE_START)

			{

			pWnd->PostMessage(WM_KEYDOWN,VK_F5,0); // Simulieren, dass die F5-Taste gedrückt wurde

												   // Zur Aktuallisierung der Dokumentenliste

												   // Und zur Prüfung des Status der Datenbank



			if(iCounter == 5) // Nur jede 10 Datenbankprüfung auch Termine Prüfen

				{

			//	pWnd->PostMessage(WM_CHECKTERMINE, 0, 0); //Prüfen ob neue Termine vorliegen

				pWnd->SendMessage(WM_CHECKTERMINE,0,0);

				iCounter = 0;

				}

			iCounter++;

			Sleep(10000);

			}


		//DATENBANKÜBERWACHUNG BEENDEN

		if(g_iDBUeberwachung == SERVICE_STOP)

			{

			return (1);

			}

		}

//	return (0);

}




/////////////////////////////////////////////////////////////////////////////

// Diaologinitialisierung


BOOL CPatient::OnInitDialog() 

{

	//Thread zur Datenbanküberwachung starten

	g_iDBUeberwachung = SERVICE_START;

	CWinThread *pThread = AfxBeginThread(DBUeberwachung, this, THREAD_PRIORITY_NORMAL);

}



void CPatient::OnCheckTermine()

{

//Hier kommt das Programm nie an, stürtzt vorher ab.

}

Wenn Du nochwas sehen willst, sag bescheid!!

Geschrieben

Probier mal folgendes:

(notfalls den Adressoperator und die Derefernzierung weglassen. Mein C++ ist etwas eingerostet :( )



BEGIN_MESSAGE_MAP(CPatient, CDialog)

	//{{AFX_MSG_MAP(CPatient)

	ON_MESSAGE(WM_CHECKTERMINE, OnCheckTermine)

	//}}AFX_MSG_MAP

END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////

// Therad definieren


//BOOL m_bThreadEnd;

UINT DBUeberwachung(void* pParam)

{

	CPatient *pWnd;

	pWnd=(CPatient*)[B]CWnd::FromHandle ( (HWND)*pParam )[/B];

	int iCounter = 0;


	//Dieser Thread überprüft alle 30 Sekunden die Verbindung zur Datenbank 

	//und aktuallisiert die die Anzeige.

	while (g_iDBUeberwachung != 5555) //ENDLOS

		{

		//DATENBANKÜBERWACHUNG AKTIV

		if(g_iDBUeberwachung == SERVICE_START)

			{

			pWnd->PostMessage(WM_KEYDOWN,VK_F5,0); // Simulieren, dass die F5-Taste gedrückt wurde

												   // Zur Aktuallisierung der Dokumentenliste

												   // Und zur Prüfung des Status der Datenbank



			if(iCounter == 5) // Nur jede 10 Datenbankprüfung auch Termine Prüfen

				{

			//	pWnd->PostMessage(WM_CHECKTERMINE, 0, 0); //Prüfen ob neue Termine vorliegen

				pWnd->SendMessage(WM_CHECKTERMINE,0,0);

				iCounter = 0;

				}

			iCounter++;

			Sleep(10000);

			}


		//DATENBANKÜBERWACHUNG BEENDEN

		if(g_iDBUeberwachung == SERVICE_STOP)

			{

			return (1);

			}

		}

//	return (0);

}




/////////////////////////////////////////////////////////////////////////////

// Diaologinitialisierung


BOOL CPatient::OnInitDialog() 

{

	//Thread zur Datenbanküberwachung starten

	g_iDBUeberwachung = SERVICE_START;

	CWinThread *pThread = AfxBeginThread(DBUeberwachung, [B]&this -> GetSafeHwnd()[/B], THREAD_PRIORITY_NORMAL);

}



void CPatient::OnCheckTermine()

{

//Hier kommt das Programm nie an, stürtzt vorher ab.

}

Geschrieben

PS:

OHNE den * bei

pWnd=(CPatient*)CWnd::FromHandle ( (HWND)[COLOR="Red"][B]*[/B][/COLOR]pParam );
lässt es sich kompilieren und stürst auch nicht ab, jedoch wird bei
pWnd->PostMessage(WM_CHECKTERMINE,0, 0); //Prüfen ob neue Termine vorliegen

//ODER

pWnd->SendMessage(WM_CHECKTERMINE,0,0);

die entsprechende Funktion nicht aufgerufen.

Geschrieben

Hi Filou,

dein Problem hat mich nicht mehr losgelassen, daher hab ich mir mal schnell ein Test Projekt nachgebaut. (Code ist mit VS .Net 2003 erstellt).

Bei mir wurde der Nachrichtenhandler ohne Probleme geöffnet als ich in der Threadfunktion PostMessage verwendet habe. Benutzt du VS 6.0? Da ist der Compiler etwas fehlertoleranter, wenn dein Nachrichtenhandler nicht die richtige Signatur für User defined messages (WM_USER) hat.

Vielleicht ist das mit ein Grund warum deine Release Build einen Fehler hat.

Hier siehst du mein Testprojekt, vielleicht hilfts dir weiter:

(Die Implementierung der Threadfunktion habe ich aus deinem Post übernommen. Wichtig ist die Signatur von OnCheckTermine)


// CThreadTestDlg Dialogfeld

class CThreadTestDlg : public CDialog

{

// Konstruktion

public:

	CThreadTestDlg(CWnd* pParent = NULL);	// Standardkonstruktor


        ...


	// Generierte Funktionen für die Meldungstabellen

	virtual BOOL OnInitDialog();

        [B]afx_msg LRESULT OnCheckTermine(WPARAM wParam, LPARAM lParam);[/B]

	DECLARE_MESSAGE_MAP()

};



#define WM_CHECKTERMINE (WM_USER+0x100)


BEGIN_MESSAGE_MAP(CThreadTestDlg, CDialog)

	ON_WM_PAINT()

	ON_WM_QUERYDRAGICON()

    ON_MESSAGE(WM_CHECKTERMINE,OnCheckTermine)

	//}}AFX_MSG_MAP

END_MESSAGE_MAP()


UINT DBUeberwachung(LPVOID pParam)

{

    CThreadTestDlg *pWnd;

	pWnd=(CThreadTestDlg*)pParam;


	int iCounter = 0;


	//Dieser Thread überprüft alle 30 Sekunden die Verbindung zur Datenbank 

	//und aktuallisiert die die Anzeige.

	while (g_iDBUeberwachung != 5555) //ENDLOS

	{

		//DATENBANKÜBERWACHUNG AKTIV

		if(g_iDBUeberwachung == SERVICE_START)

		{

			pWnd->PostMessage(WM_KEYDOWN,VK_F5,0); // Simulieren, dass die F5-Taste gedrückt wurde

												   // Zur Aktuallisierung der Dokumentenliste

												   // Und zur Prüfung des Status der Datenbank



			if(iCounter == 5) // Nur jede 10 Datenbankprüfung auch Termine Prüfen

			{

			    pWnd->PostMessage(WM_CHECKTERMINE, 0, 0); 


				iCounter = 0;

			}


			iCounter++;


			Sleep(1000);

			}


		//DATENBANKÜBERWACHUNG BEENDEN

		if(g_iDBUeberwachung == SERVICE_STOP)

		{

			return (1);

		}

	}


	return (0);

}



BOOL CThreadTestDlg::OnInitDialog()

{

	CDialog::OnInitDialog();


	// Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt

	//  wenn das Hauptfenster der Anwendung kein Dialogfeld ist

	SetIcon(m_hIcon, TRUE);			// Großes Symbol verwenden

	SetIcon(m_hIcon, FALSE);		// Kleines Symbol verwenden


	g_iDBUeberwachung = SERVICE_START;


    CWinThread *pThread = AfxBeginThread ( DBUeberwachung, this, THREAD_PRIORITY_NORMAL );


	return TRUE;

}


[B]LRESULT CThreadTestDlg::OnCheckTermine(WPARAM wParam, LPARAM lParam)[/B]

{

    CAboutDlg dlg;


    dlg.DoModal();


    return 0;

}


Geschrieben

Hey erstmal vielen Dank, dass Du Dir soviel Mühe gemacht hast!

Das ist wirklich super!!

Ich hatte gestern Urlaub und konnte es nicht testen.

Heute Morgen habe ich aber alles aus Deinem Beispiel übernommen und es klappt jetzt ohne Probleme!! :uli :uli :uli :uli

Tausenmal DANKE!! :)

Das ist echt geil!!

Wüsster jetzt gern worans gelegen hat?!

Vielleicht lags an meiner Funktionsdefinition:

void CPatient::OnCheckTermine()
Wieso hast Du es so gemacht:
LRESULT CPatient::OnCheckTermine(WPARAM wParam, LPARAM lParam)

Geschrieben

Toll, dass es jetzt klappt.

Ich habe die Funktionssignatur genommen, weil es die standardsignatur für user defined messages der MFC ist. Wenn du Visual Studio 6.0 verwendest dann compiliert alles ohne Probleme. Compilierst du den selben Code z.B. mit Visual Studio .Net 2003 meckert der Compiler sofort wenn deine Funktion nicht dieser Signatur entspricht.

Ob das jetzt wirklich genau der Grund war kann ich nicht 100% beantworten aber es ist durchaus möglich da der Absturz nur im Release Build aufgetreten ist.

Freut mich auf jeden Fall wenn ich helfen konnte.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...