malloc Crash
-
Hi nochmal,
so, da sich das andere Problem mit _realloc sozusagen selbst aufgelöst hat, hier nun unser neues Problem, gleicher Bauart:
class CMoooh { public: CMoooh(); public: char* blubb; };CMoooh::CMoooh() { blubb = NULL; } void Test() { CMoooh cif; cif.blubb = new char[32000]; // Hier! }Jener Code (sinnwahrend gekürzt) stürzt an mit "Hier!" markierter Stelle ab. Unabhängig davon, wie groß der Puffer ist. Warum? Was ist da falsch? Der Stacktrace verweist zuletzt auf einen malloc-Aufruf.
Danke!
Grüße, Hendrik
-
Kannst du im Stack mal etwas nach oben gehen, um zu sehen, von wo aus malloc() aufgerufen wird? (auch wenn's nicht erforderlich ist, wird operator new oft auf malloc() zurückgeführt)
PS: Und deine Probleme dürften nicht von der Anweisung (bzw. dem realloc()-Aufruf aus deinem letzten Thread) stammen - du hast dir irgendwo anders mächtig den Heap zerlegt, indem du irgendwo über das Ende des angeforderten Speicherbereiches hinausgeschrieben hast. (im Debug-Modus waren dort vermutlich "nur" Füllbytes als Sicherheitszone, im Release-Modus aber Steuerdaten des Heap-Managers)
-
Ist Dein Heap zu diesem Zeitpunkt evtl. schon zerstört, wenn diese Funktion aufgerufen wird?
Was steht in Der Debug Ausgabe? Wie lautet die ASSERT Zeile?
-
Gibt es nicht 'ne Software, die mir genau dieses über die Heapgrenzen hinaus Schreiben melden kann? Ich meine, mal sowas gehört zu haben.
Wie mache ich einen Stacktrace von einem Fehler, der im Debugger nicht aufzutreten scheint?
-
SeveQ schrieb:
Gibt es nicht 'ne Software, die mir genau dieses über die Heapgrenzen hinaus Schreiben melden kann? Ich meine, mal sowas gehört zu haben.
Ja, gibt es, mir fällt da ad hoc Boundschecker ein.
Wie mache ich einen Stacktrace von einem Fehler, der im Debugger nicht aufzutreten scheint?
Du hast entweder ein Initialisierungsproblem oder schreibst irgendwo mit einem (wahrscheinlich zu weit inkrementierten) Index oder Pointer in Speicherbereiche, die Du nicht allokiert hast.
-
Okay, also hier mal der Stacktrace des Absturzes beim 'new'. Hoffe, es kann jemand damit was anfangen (Access Violation 0xC0000005 at 0x7C911C20).
Aber ich glaub, wir ham's gleich... Timing Problem zwischen Threads, vermutlich. Das ganze läuft ja in 'nem COM Objekt. Und da wird vermutlich von verschiedenen Seiten gleichzeitig auf den Heap zugegriffen und selbiger dadurch völlig verhunzt. Also unser'n Code alles in 'ne Critical Section... mal sehen, ob das Abhilfe schafft.
Weitere Kommentare sind gern gesehen!
EDIT: Übrigens, zum Thema BoundsChecker... wo findet man den denn? NuMega gibt's ja nun schon 'ne ganze Weile nicht mehr? Wurde der irgendwo weiterentwickelt? Andere Software, die genau in diese Kerbe haut?
Trace:
Stack Frames at EIP: 0x7C911C20 - PID: 3244 TID: 3836 0x7C911C20: ntdll.dll:RtlInitializeCriticalSection + 0x00F3 0x7C91825D: ntdll.dll:RtlReAllocateHeap + 0x0860 0x7C911C76: ntdll.dll:RtlInitializeCriticalSection + 0x0149 0x10212F4C: MSVCR80D.dll!_heap_alloc_base + 0x005C <Void *> 0x1021AE15: MSVCR80D.dll!_heap_alloc_dbg + 0x01F5 <Void *> 0x1021ABA9: MSVCR80D.dll!_nh_malloc_dbg + 0x0019 <Void *> 0x1021AB29: MSVCR80D.dll!malloc + 0x0019 <Void *> 0x1026908F: MSVCR80D.dll!operator new + 0x000F <Void *> 0x034A3739: IDA.DLL!CMMLEvents::OnCommand + 0x00F9 <Hresult> 0x771273D0: OLEAUT32.DLL!DispCallFunc + 0x00C3 0x0349EC35: IDA.DLL!ATL::IDispEventSimpleImpl<1,CMMLEvents,&Ists::DIID_IMMLEvents>::InvokeFromFuncInfo + 0x01B5 <Hresult> 0x0349E585: IDA.DLL!ATL::IDispEventSimpleImpl<1,CMMLEvents,&Ists::DIID_IMMLEvents>::Invoke + 0x00F5 <Hresult> 0x7719BF39: OLEAUT32.DLL!VarDecCmpR8 + 0x125F 0x7719B1BD: OLEAUT32.DLL!VarDecCmpR8 + 0x04E3 0x77EF4047: RPCRT4.DLL!NdrProxyFreeBuffer + 0x00B5 0x77EF3BF3: RPCRT4.DLL!CStdStubBuffer_Invoke + 0x0082 0x7717E5F0: OLEAUT32.DLL!VarMonthName + 0xD050 0x77600C31: OLE32.DLL!StgGetIFillLockBytesOnFile + 0x10439 0x77600BDB: OLE32.DLL!StgGetIFillLockBytesOnFile + 0x103E3 0x7750F237: OLE32.DLL!CoReleaseMarshalData + 0x07DC 0x7750F15C: OLE32.DLL!CoReleaseMarshalData + 0x0701 0x7750FC79: OLE32.DLL!DcomChannelSetHResult + 0x05BA 0x77600E3B: OLE32.DLL!StgGetIFillLockBytesOnFile + 0x10643 0x776009BC: OLE32.DLL!StgGetIFillLockBytesOnFile + 0x101C4 0x77600DF2: OLE32.DLL!StgGetIFillLockBytesOnFile + 0x105FA 0x7750FCB3: OLE32.DLL!DcomChannelSetHResult + 0x05F4 0x7750FAE9: OLE32.DLL!DcomChannelSetHResult + 0x042A 0x77D48734: USER32.DLL!GetDC + 0x006D 0x77D48816: USER32.DLL!GetDC + 0x014F 0x77D489CD: USER32.DLL!GetWindowLongW + 0x0127 0x7750FA56: OLE32.DLL!DcomChannelSetHResult + 0x0397 0x77D48A10: USER32.DLL!DispatchMessageW + 0x000F 0x77512C02: OLE32.DLL!CoImpersonateClient + 0x01D3 0x77512BD2: OLE32.DLL!CoImpersonateClient + 0x01A3 0x77512B76: OLE32.DLL!CoImpersonateClient + 0x0147 0x77512B33: OLE32.DLL!CoImpersonateClient + 0x0104 0x7751235C: OLE32.DLL!CoUnmarshalInterface + 0x1509 0x776017A2: OLE32.DLL!StgGetIFillLockBytesOnFile + 0x10FAA 0x776011B6: OLE32.DLL!StgGetIFillLockBytesOnFile + 0x109BE 0x7760109A: OLE32.DLL!StgGetIFillLockBytesOnFile + 0x108A2 0x77512409: OLE32.DLL!CoUnmarshalInterface + 0x15B6 0x775123B2: OLE32.DLL!CoUnmarshalInterface + 0x155F 0x77510414: OLE32.DLL!DcomChannelSetHResult + 0x0D55 0x77EF3DB5: RPCRT4.DLL!NdrProxySendReceive + 0x0040 0x77EF3EAC: RPCRT4.DLL!NdrProxySendReceive + 0x0137 0x77EF3E42: RPCRT4.DLL!NdrProxySendReceive + 0x00CD 0x77E89AA4: RPCRT4.DLL!NdrComplexArrayMemorySize + 0x0695 0x0349D4AF: IDA.DLL!CISTSConnection::SendMMLCommand + 0x009F <Hresult> 0x0349A8DA: IDA.DLL!CidaRowset::fInitISTS + 0x00AA <Hresult> 0x03459921: IDA.DLL!CidaRowset::Execute + 0x0121 <Hresult> 0x0349C52D: IDA.DLL!ATL::ICommandImpl<CidaCommand,ICommandText>::CreateRowset<CidaRowset> + 0x084D <Hresult> 0x0349A7BE: IDA.DLL!CidaCommand::Execute + 0x003E <Hresult> 0x4DE3062D: msado15.dll!DllCanUnloadNow + 0x6737 0x4DE3AAAE: msado15.dll!DllCanUnloadNow + 0x10BB8 0x4DE1A2B9: msado15.dll!DllGetClassObject + 0x297E 0x4DE1A1C2: msado15.dll!DllGetClassObject + 0x2887 0x4DE19EDB: msado15.dll!DllGetClassObject + 0x25A0 0x4DE2ED72: msado15.dll!DllCanUnloadNow + 0x4E7C 0x6502124A: VBE6.DLL!rtcDoEvents + 0x1622 0x771273D0: OLEAUT32.DLL!DispCallFunc + 0x00C3 0x6509C10E: VBE6.DLL!DllVbeTerm + 0xB948 0x77D48734: USER32.DLL!GetDC + 0x006D 0x650BED01: VBE6.DLL!rtcShell + 0x1EE21 0x650BEC19: VBE6.DLL!rtcShell + 0x1ED39 0x65032E24: VBE6.DLL!VarPtr + 0xA29E 0x651FB534: VBE6.DLL!rtcStrConvVar2 + 0x129A1 0x60012EDD: FM20.DLL!DllGetClassObject + 0x1099D 0x60015E3D: FM20.DLL!DllGetClassObject + 0x138FD 0x77D48734: USER32.DLL!GetDC + 0x006D 0x77D48816: USER32.DLL!GetDC + 0x014F 0x6000D2EF: FM20.DLL!DllGetClassObject + 0xADAF 0x6001AAC4: FM20.DLL!DllGetClassObject + 0x18584 0x6001AEBC: FM20.DLL!DllGetClassObject + 0x1897C 0x60015E3D: FM20.DLL!DllGetClassObject + 0x138FD 0x77D48734: USER32.DLL!GetDC + 0x006D 0x77D48816: USER32.DLL!GetDC + 0x014F 0x77D489CD: USER32.DLL!GetWindowLongW + 0x0127 0x77D48A10: USER32.DLL!DispatchMessageW + 0x000F 0x30022A3F: EXCEL.EXE:Ordinal44 + 0x22A3F 0x30001F67: EXCEL.EXE:Ordinal44 + 0x1F67 0x30001CAB: EXCEL.EXE:Ordinal44 + 0x1CAB 0x7C816FD7: KERNEL32.DLL!RegisterWaitForInputIdle + 0x0049
-
Der Stack Trace sagt mir so nichts. Vermutlkich ist der Heap schon zerstört.
Man kann auch einfach an einigen Stellen, die oft aufgerufen werden
ASSERT(AfxCheckMemory());Einbauen. Dieser Assert meldet sich sofort wen man Speicher illegal über Grenzen hinweg überschreibt.
-
Habe ich vergessen:
Man kann auch _CrtSetDbgFlag _CRTDBG_CHECK_ALWAYS_DF verwenden. Dann wird sofort nach jeder Allokation ein Heap Check durchgeführt.
Wurde er in der zwischenzeit zerstört, dann hat man zumindest einen nahen Anhaltspunkt._CRTDBG_DELAY_FREE_MEM_DF kann auch noch helfen...
-
SeveQ schrieb:
EDIT: Übrigens, zum Thema BoundsChecker... wo findet man den denn?
gibt da so ne ganz verrückte neue erfindung die heißt suchmaschine. die findet sachen im internet wenn man ihr sagt was man sucht. muss man nur kennen. eine von denen heißt guhgl oder so ähnlich, da hab ich mal "boundschecker" eingegeben und die hat tatsächlich rausgefunden wo es das gibt!!!1 krass, ne?
-
medienkompetenz schrieb:
SeveQ schrieb:
EDIT: Übrigens, zum Thema BoundsChecker... wo findet man den denn?
gibt da so ne ganz verrückte neue erfindung die heißt suchmaschine. die findet sachen im internet wenn man ihr sagt was man sucht. muss man nur kennen. eine von denen heißt guhgl oder so ähnlich, da hab ich mal "boundschecker" eingegeben und die hat tatsächlich rausgefunden wo es das gibt!!!1 krass, ne?
Naja, gaaaaanz doof bin ich auch nicht, nur anscheinend doof genug, daß ich's da nicht finde. Da hab ich nämlich natürlich zuerst geschaut.
Mal wieder klarer Fall vonSeveQ vs. Google... and the Winner is: Google!
-
SeveQ schrieb:
EDIT: Übrigens, zum Thema BoundsChecker... wo findet man den denn? NuMega gibt's ja nun schon 'ne ganze Weile nicht mehr? Wurde der irgendwo weiterentwickelt? Andere Software, die genau in diese Kerbe haut?
IIRC dann ist BoundsChecker bei Compuware gelandet.