malloc()/free()-Crash
-
Hi,
ich habe eine Applikation, die lädt während der Laufzeit eine DLL (mittels LoadLibrary()) und holt sich dann die Einsprungadressen verschiedener, in dieser DLL enthaltener Funktionen.
Anschließend gibt es folgenden Ablauf:
- es wird eine DLL-Funktion aufgerufen, innerhalb dieser Funktion wird mit malloc() ein Speicherbereich alloziiert
- der Speicherbereich wird an die Hauptapplikation zurückgeliefert
- es wird free() aufgerufen, um den Speicher wieder freizugebenUnd hier ist mein Problem: dieses free() schlägt mit einem Crash fehl. Das sollte ja eigentlich nicht sein, da die DLL doch zum Prozess dess Hauptptogrammes gehört?
Und noch viel lustiger: Wenn ich exakt die gleiche Prozedur unter Linux mit einer Library und dlopen() anwende, dann gibt es keinen Crash, dort wird der Speicherbereich anstandslos freigegeben.
Das kann doch also eigentlich nicht sein, dass es unter Windows nicht klappt - was habe ich hier übersehen?
-
Nachtrag: es scheint ein Problem mit irgend einer Compile-Option des VC6 zu sein.
malloc() liefert z.B. die Adresse 0x00bf9cd8 zurück, der Crash kommt dann mit einer Debug-Meldung "Invalid Address specified to RtlValidateHeap( 00C30000, 00BF9CB8 )" ,d.h. es wird veruscht, Adresse 0xbf9cb8 freizugeben.
Was macht der VC6 da?
-
Ich würde den Speicher in der DLL selbst wieder freigeben:
http://stackoverflow.com/questions/132242/does-a-memory-leak-at-unload-of-a-dll-cause-a-leak-in-the-host-process
-
die dll könnte ihre eigene version von malloc/free mitbringen, deshalb sollte sie auch selber ihren allozierten speicher wieder freigeben. oder ihr benutzt VirtualAlloc/VirtualFree usw, das ist prozessweit eindeutig.
btw, diese verschiebung um 8 bits nach rechts ist aber schon seltsam, da ist bestimmt noch was anderes faul.

-
Ich bin zumindest ein bissl weiter gekommen: Das Problem tritt unter windows auch nur in der Debug-Version auf, mit der Release klappt free() problemlos.
Mittlerweile wird sowohl in der Applikation als auch in der DLL (in der Debug-Version) die crtdbg.h includiert (die hat in der DLL vorher gefehlt), leider hat das auch nichts geholfen, der komische Offset in der Adresse is immer noch da...
-
Hast Du den Link gelesen?
Was für eine CRT verwendest Du? DLL/static?
Vermeide Allokationen in der DLL und Freigaben in der EXE (u.u.) wie die Pest!
Wenn Du das machst, musst Du garantieren, dass sowohl EXE als auch DLL die DLL Version der CRT in der gleichern Version nutzen!
-
Martin Richter schrieb:
Hast Du den Link gelesen?
Was für eine CRT verwendest Du? DLL/static?
Ähm wo sehe ich das?
-
Keine Ahnung? Was hast Du für eine Entwicklungsumgebung?
Ichkann Dir sagen wo ich es bei mir in VS-200x finde

Project Properties -> C++ -> Code Generation -> Runtime Library
-
Hmmmm, steht bei beiden auf "(Debug) Multithreaded DLL" ...
-
Dann würde ich mal sagen, dass Du einen anderen Zeiger freigibst als Du allokierst.
-
Definitiv nein:
1. funktioniert exakt der gleiche Code unter Linux bzw. in der Windows Release Version
2. kann ich sehen, dass beim Aufruf von free() noch eine ganz andere (nämlich die richtige) Adresse übergeben wird - erst die Debug-Fehlermeldung zeigt dann eine andere als die übergebene Adresse an.
-
Andere Frage: Ist die eine Version eine Debug-Version, die andere eine Release Version?
Das geht auch nicht!
-
Nein, es sind immer beides Debug- bzw. Release-Versionen.