Thread - Heap Corruption
-
Hallo Leute

Ich sammle gerade die ersten Erfahrungen mit Thread und stosse (natürlicherweise *g*) auf Probleme.
Die Sache ist die, dass ich eine Funktion, die zyklisch aufgerufen wird (aber auch manuell über einen Button) in einen Thread auslagern will.
Das funktioniert im Prinzip sehr gut, bis zum Ende des Threads.Kommt der Thread zum Ende, zeigt sich diese Fehlermeldung:
"Windows has triggered a breakpoint in comm.exe
This may be due to a corruption of the heap, and indicates a bug in comm.exe or any of the DLLs it has loaded.
The output window may have more diagnostic information"Wenn die Funktion nicht im Thread läuft, kann ich es auch mehrere Tage durchlaufen lassen. Ich hab auch mehrere ASSERT(AfxCheckMemory()) durch den Code gestreut, aber keine Meldungen...
UINT AnfrageAndRead(LPVOID pParam) //////////////////////////////////////////////////////////////////////////////////////////// { CCommDlg* dlg = (CCommDlg*)CWnd::FromHandle((HWND)pParam); int cnt = 0; dlg->Anfrage(); Sleep(5000); cnt = dlg->Read(); Sleep(5000); cnt += dlg->Read(); ASSERT(AfxCheckMemory()); return 0; }Was da passiert?
Ich sende eine Anfrage an ein anderes System, das stellt Antworten in eine Queue, die dann abgeholt werden. Read wird zwei mal aufgerufen, weil es sein kann, dass beim ersten Mal weitere Anfragen gesendet werden.Naja, ich hoffe ich stelle genügend Infos bereit - Ansonsten einfach Fragen

Vielen Dank schon mal..
lg
Willie
-
AfxCheckMemory ist eine Möglichkeit.
Es geht auch durch setzen von _CRTDBG_CHECK_ALWAYS_DF mit _CrtSetDbgFlag, dann wird immer bei jeder Allokation ein Heapcheck durchgeführt!Wenn dieser ASSERT auftritt, dann schau mal in den Stack-Trace! Was dort gerade evtl. freigebenen wird.
Evtl. gibst Du einen Zeiger zweimal frei.Es ist grundsätzlich schlecht. MFC Objekte in einen anderen Thread zu übergeben. Solange Anfrage und Read selbst keine MFC-Handle-Objekte verwenden ist das OK.
Ich würde soetwas eher in ein Interface oder eine kleine eigene Klasse auslagern und keinen CDialog für so etwas verwenden.
-
Hey,
_CRTDBG_CHECK_ALWAYS_DF bringt keine Änderung.
Vom Call Stack werd ich nicht schlauer.... Das steht da drinnen
_threadstart
_threadstartex
AfxThreadEntry
AfxEndThread
_endthreadex
freefls -> hier fliegt er bei der Zeile:_free_crt((void *)ptd);Dateiname: tidtable.c
Eigentlich dachte ich mir schon, dass etwas grundsätzlich nicht stimmt und deswegen werd ich es als nächstes so umbauen, dass im Thread keine Methoden des Dialogs verwendet werden.
Die Funktionen Anfrage und Read rufen im Prinzip eh eine andere Klasse auf - aber wieso einfach wenn's kompliziert geht?
naja vielen Dank einmal, ich mach mich mal an die Arbeit

lg
Willie
-
Was machst Du denn mit dem Thread Objekt? Gibst Du das evtl. auch selber frei?
Evtl. hat die letzte Operation genau bevor das Thread Objekt zerstört wird, den Heap zerstört.
Ich befürchte das irgend was den Speicher überschreibt...BTW: Du darfst Methoden von CDialog ausführen. Nur kommt an dann oft genug durcheinander, wenn es um die Daten des Dialoges geht. Denn der Zugriff auf die müsste ja abgesichert werden. Ich mag deswegen nicht wenn an Workerthreads GUI Objekte weitergereicht werden...
-
Ich speichere das Thread-Objekt nicht.
Der Thread zerstört sich selbst, wenn er fertig ist.Wegen den Methoden aus dem CDialog -> da hätte ich Mutexe eingebaut. Aber wie gesagt, das ist mein erster Thread und so sicher war ich mir da nicht.
Ich hätte es jetzt umgebaut, der Fehler kommt leider nach wie vor und ich habe ihn eingegrenzt...vermute ich *g*
[schnipp]
[/schnapp]Fehler gefunden... Es lag am Schliessen der Verbindung zur Queue. Da wird ein returncode übertragen und der wurde in eine ungültige Variable geschrieben.
Interessant nur, dass der Fehler erst mit dem Thread auftrat und das Programm vorher Tagelang durchlief. Dürfte wohl im Thread ein "wichtigerer" Speicher überschrieben worden sein.
Ich liebe Speicherfehler *g*Naja, vielen Dank für deine Hilfe (die mir eh ab und an schon geholfen hat - du Allrounder
)lg
Willieedit: OK, das war's doch nicht
