I am trying to track down a crash when exiting an application. Here is what I think are relevant parts of the trace. Does it appear that I am in the right area? Any hints on how to proceed would be appreciated.
08073208:Call comctl32.ImageList_Destroy(41691ba0) ret=005027f5 08073208:Call gdi32.DeleteObject(0000098c) ret=409fcadd 08073208:Call x11drv.DeleteBitmap(0000098c) ret=4078081b 08073208:Call gdi32.GDI_GetObjPtr(0000098c,00004f4b) ret=40adcfe4 08073208:Ret gdi32.GDI_GetObjPtr() retval=40279910 ret=40adcfe4 08073208:Call gdi32.GDI_ReleaseObj(0000098c) ret=40add01e 08073208:Ret gdi32.GDI_ReleaseObj() retval=00000000 ret=40add01e 08073208:Ret x11drv.DeleteBitmap() retval=00000001 ret=4078081b trace:heap:RtlFreeHeap (0x40230000,00000002,40279910): returning TRUE 08073208:Ret gdi32.DeleteObject() retval=00000001 ret=409fcadd 08073208:Call gdi32.DeleteObject(00000990) ret=409fcaea 08073208:Call x11drv.DeleteBitmap(00000990) ret=4078081b 08073208:Call gdi32.GDI_GetObjPtr(00000990,00004f4b) ret=40adcfe4 08073208:Ret gdi32.GDI_GetObjPtr() retval=402799c8 ret=40adcfe4 08073208:Call gdi32.GDI_ReleaseObj(00000990) ret=40add01e 08073208:Ret gdi32.GDI_ReleaseObj() retval=00000000 ret=40add01e 08073208:Ret x11drv.DeleteBitmap() retval=00000001 ret=4078081b trace:heap:RtlFreeHeap (0x40230000,00000002,402799c8): returning TRUE 08073208:Ret gdi32.DeleteObject() retval=00000001 ret=409fcaea 08073208:Call gdi32.DeleteObject(00001282) ret=409fcaf7 trace:heap:RtlFreeHeap (0x40230000,00000002,40279ac0): returning TRUE trace:heap:RtlFreeHeap (0x40230000,00000002,40279a58): returning TRUE 08073208:Call kernel32.LOCAL_Free(000001b7,00001282) ret=4078e36f 08073208:Ret kernel32.LOCAL_Free() retval=00000000 ret=4078e36f 08073208:Ret gdi32.DeleteObject() retval=00000001 ret=409fcaf7 08073208:Call gdi32.DeleteObject(00001286) ret=409fcb04 trace:heap:RtlFreeHeap (0x40230000,00000002,40279b28): returning TRUE trace:heap:RtlFreeHeap (0x40230000,00000002,40279ae0): returning TRUE 08073208:Call kernel32.LOCAL_Free(000001b7,00001286) ret=4078e36f 08073208:Ret kernel32.LOCAL_Free() retval=00000000 ret=4078e36f 08073208:Ret gdi32.DeleteObject() retval=00000001 ret=409fcb04 trace:commctrl:COMCTL32_Free (0x41691ba0) trace:heap:RtlFreeHeap (0x41690000,00000002,41691ba0): returning TRUE 08073208:Ret comctl32.ImageList_Destroy() retval=00000001 ret=005027f5
The next mention of 41691ba0 is
08073208:Call window proc 0x40a0f0c8 (hwnd=0x1002e,msg=LVM_GETIMAGELIST,wp=00000001,lp=00000000) 08073208:Call kernel32._ConfirmSysLevel(4070bc18) ret=406b681d 08073208:Ret kernel32._ConfirmSysLevel() retval=00000000 ret=406b681d 08073208:Call user32.GetWindowLongW(0001002e,00000000) ret=40a0f0e5 08073208:Ret user32.GetWindowLongW() retval=41690a18 ret=40a0f0e5 trace:listview:LISTVIEW_WindowProc (uMsg=1002 wParam=1 lParam=0) 08073208:Call user32.GetWindowLongW(0001002e,fffffff0) ret=40a0f164 08073208:Ret user32.GetWindowLongW() retval=40018405 ret=40a0f164 08073208:Call kernel32.GlobalGetAtomNameW(0000c012,4070ce90,0000003c) ret=40693ce9 08073208:Ret kernel32.GlobalGetAtomNameW() retval=0000000d ret=40693ce9 08073208:Call kernel32.lstrcpynW(4070cf08,40274130 L"List1",00000010) ret=406b9fe6 08073208:Ret kernel32.lstrcpynW() retval=4070cf08 ret=406b9fe6 08073208:Ret window proc 0x40a0f0c8 (hwnd=0x1002e,msg=LVM_GETIMAGELIST,wp=00000001,lp=00000000) retval=41691ba0 08073208:Ret user32.CallWindowProcA() retval=41691ba0 ret=005050d2 08073208:Ret user32.CallWindowProcA() retval=41691ba0 ret=005050d2 08073208:Call kernel32.GlobalGetAtomNameW(0000c012,4070ce90,0000003c) ret=40693ce9 08073208:Ret kernel32.GlobalGetAtomNameW() retval=0000000d ret=40693ce9 08073208:Call kernel32.lstrcpynW(4070cf08,40274130 L"List1",00000010) ret=406b9fe6 08073208:Ret kernel32.lstrcpynW() retval=4070cf08 ret=406b9fe6 08073208:Ret window proc 0x5048bf (hwnd=0x1002e,msg=LVM_GETIMAGELIST,wp=00000001,lp=00000000) retval=41691ba0
So it appears to still get the imagelist, even though it has been destroyed. Then the next mention is where it gives a bad ptr message.
08073208:Call window proc 0x503959 (hwnd=0x1002d,msg=WM_NOTIFY,wp=0000041b,lp=40581ea4) 08073208:Call kernel32._ConfirmSysLevel(4070bc18) ret=406b681d 08073208:Ret kernel32._ConfirmSysLevel() retval=00000000 ret=406b681d 08073208:Call kernel32.GlobalFindAtomW(406f3982 L"PropertySheetInfo") ret=406d7488 08073208:Ret kernel32.GlobalFindAtomW() retval=00000000 ret=406d7488 08073208:Call kernel32.GlobalGetAtomNameW(00008002,4070ce90,0000003c) ret=40693ce9 08073208:Ret kernel32.GlobalGetAtomNameW() retval=00000007 ret=40693ce9 08073208:Call kernel32.lstrcpynW(4070cf08,402757e8 L"Conference Information Window",00000010) ret=406b9fe6 08073208:Ret kernel32.lstrcpynW() retval=4070cf08 ret=406b9fe6 08073208:Ret window proc 0x503959 (hwnd=0x1002d,msg=WM_NOTIFY,wp=0000041b,lp=40581ea4) retval=00000000 08073208:Call kernel32.GlobalFindAtomW(406f3982 L"PropertySheetInfo") ret=406d7488 08073208:Ret kernel32.GlobalFindAtomW() retval=00000000 ret=406d7488 08073208:Call kernel32.GlobalGetAtomNameW(00008002,4070ce90,0000003c) ret=40693ce9 08073208:Ret kernel32.GlobalGetAtomNameW() retval=00000007 ret=40693ce9 08073208:Call kernel32.lstrcpynW(4070cf08,402757e8 L"Conference Information Window",00000010) ret=406b9fe6 08073208:Ret kernel32.lstrcpynW() retval=4070cf08 ret=406b9fe6 08073208:Ret window proc 0x4069aaf8 (hwnd=0x1002d,msg=WM_NOTIFY,wp=0000041b,lp=40581ea4) retval=00000000 08073208:Ret user32.CallWindowProcA() retval=00000000 ret=005050d2 08073208:Call kernel32.GlobalFindAtomW(406f3982 L"PropertySheetInfo") ret=406d7488 08073208:Ret kernel32.GlobalFindAtomW() retval=00000000 ret=406d7488 08073208:Call kernel32.GlobalGetAtomNameW(00008002,4070ce90,0000003c) ret=40693ce9 08073208:Ret kernel32.GlobalGetAtomNameW() retval=00000007 ret=40693ce9 08073208:Call kernel32.lstrcpynW(4070cf08,402757e8 L"Conference Information Window",00000010) ret=406b9fe6 08073208:Ret kernel32.lstrcpynW() retval=4070cf08 ret=406b9fe6 08073208:Ret window proc 0x5048bf (hwnd=0x1002d,msg=WM_NOTIFY,wp=0000041b,lp=40581ea4) retval=00000000 08073208:Call kernel32.GlobalLock16(0000020f) ret=406ae141 08073208:Ret kernel32.GlobalLock16() retval=4025f210 ret=406ae141 08073208:Ret user32.SendMessageW() retval=00000000 ret=40a00f12 trace:listview:notify_hdr <= 0 trace:listview:LISTVIEW_NCDestroy Start destroying data structures. trace:commctrl:DPA_Destroy (0x41690e10) trace:heap:RtlFreeHeap (0x41690000,00000002,41690e30): returning TRUE trace:heap:RtlFreeHeap (0x41690000,00000002,41690e10): returning TRUE trace:commctrl:DPA_Destroy (0x41690e88) trace:heap:RtlFreeHeap (0x41690000,00000002,41690ea8): returning TRUE trace:heap:RtlFreeHeap (0x41690000,00000002,41690e88): returning TRUE trace:commctrl:DPA_Destroy (0x41690f00) trace:heap:RtlFreeHeap (0x41690000,00000002,41690f20): returning TRUE trace:heap:RtlFreeHeap (0x41690000,00000002,41690f00): returning TRUE trace:commctrl:DPA_Destroy (0x41690f78) trace:heap:RtlFreeHeap (0x41690000,00000002,41690f98): returning TRUE trace:heap:RtlFreeHeap (0x41690000,00000002,41690f78): returning TRUE trace:commctrl:DPA_DeleteAllPtrs (0x41690d98) trace:heap:RtlFreeHeap (0x41690000,00000002,41690db8): returning TRUE trace:heap:RtlAllocateHeap (0x41690000,0000000a,00000050): returning 41690d20 trace:commctrl:DPA_Destroy (0x41690d98) trace:heap:RtlFreeHeap (0x41690000,00000002,41690d20): returning TRUE trace:heap:RtlFreeHeap (0x41690000,00000002,41690d98): returning TRUE trace:commctrl:COMCTL32_Free (0x41690d78) trace:heap:RtlFreeHeap (0x41690000,00000002,41690d78): returning TRUE trace:listview:LISTVIEW_NCDestroy Start destroying image lists. 08073208:Call gdi32.DeleteObject(aaaaaaaa) ret=409fcadd 08073208:Ret gdi32.DeleteObject() retval=00000000 ret=409fcadd 08073208:Call gdi32.DeleteObject(aaaaaaaa) ret=409fcaea 08073208:Ret gdi32.DeleteObject() retval=00000000 ret=409fcaea 08073208:Call gdi32.DeleteObject(aaaaaaaa) ret=409fcaf7 08073208:Ret gdi32.DeleteObject() retval=00000000 ret=409fcaf7 08073208:Call gdi32.DeleteObject(aaaaaaaa) ret=409fcb04 08073208:Ret gdi32.DeleteObject() retval=00000000 ret=409fcb04 trace:commctrl:COMCTL32_Free (0x41691ba0) err:heap:HEAP_ValidateFreeArena Heap 41690000: bad next ptr 00000000 for arena 41691b98 Heap: 41690000 Next: 41680000 Sub-heaps: 41690000 Free lists: Block Stat Size Id 41690038 free 00000001 prev=41692180 next=41691ca0 4169004c free 00000001 prev=41691de0 next=416900b0 41690060 free 00000001 prev=41690988 next=41691d28 41690074 free 00000001 prev=41691fa0 next=41690d18
Sub-heap 41690000: size=00110000 committed=00010000
Block Stat Size Id 41690090 used 00000018 416900b0 free 00000078 prev=4169004c next=41690988 41690138 Used 00000088 back=416900b0 416901c8 used 00000088 41690258 used 000000c0 41690320 free 00000638 prev=41690d18 next=41692180 41690968 Used 00000018 back=41690320 41690988 free 00000058 prev=416900b0 next=41690060 416909f0 Used 00000018 back=41690988 41690a10 used 00000300 41690d18 free 000002c0 prev=41690074 next=41690320 41690fe8 Used 00000300 back=41690d18 416912f0 used 00000050 41691348 used 00000018 41691368 used 00000018 41691388 used 00000050 416913e0 used 00000018 41691400 used 00000050 41691458 used 00000018 41691478 used 00000050 416914d0 used 00000018 416914f0 used 00000050 41691548 used 00000018 41691568 used 00000050 416915c0 used 00000300 416918c8 used 00000050 41691920 used 00000018 41691940 used 00000018 41691960 used 00000050 416919b8 used 00000018 416919d8 used 00000050 41691a30 used 00000018 41691a50 used 00000050 41691aa8 used 00000018 41691ac8 used 00000050 41691b20 used 00000018 41691b40 used 00000050 41691b98 free 000000d8 prev=00000000 next=00000000 41691c80 Used 00000018 back=41691b98 41691ca0 free 00000010 prev=41690038 next=41691ec0 41691cc0 Used 00000018 back=41691ca0 41691ce0 used 00000020 41691d08 used 00000018 41691d28 free 00000088 prev=41690060 next=41691b98 41691dc0 Used 00000018 back=41691d28 41691de0 free 00000008 prev=41691ec0 next=4169004c 41691df8 Used 00000018 back=41691de0 41691e18 used 00000060 41691e80 used 00000018 41691ea0 used 00000018 41691ec0 free 00000008 prev=41691ca0 next=41691de0 41691ed8 Used 00000018 back=41691ec0 41691ef8 used 00000018 41691f18 used 00000060 41691f80 used 00000018 41691fa0 free 000001b0 prev=41691b98 next=41690074 41692160 Used 00000018 back=41691fa0 41692180 free 0010de70 prev=41690320 next=41690038
Total: Size=00110000 Committed=00010000 Free=0010eb68 Used=000011e0 Arenas=000002b8 (0%)
Duane Clark wrote:
I am trying to track down a crash when exiting an application. Here is what I think are relevant parts of the trace. Does it appear that I am in the right area? Any hints on how to proceed would be appreciated.
I think the problem comes down to this. The application explicitly destroys the imagelist that belongs to a listview:
08073208:Call comctl32.ImageList_Destroy(41691ba0) ret=005027f5 ...
That area is then freed. When freed, COMCTL32_Free writes prev and next entries into himl.
trace:commctrl:COMCTL32_Free (0x41691ba0) trace:heap:RtlFreeHeap (0x41690000,00000002,41691ba0): returning TRUE 08073208:Ret comctl32.ImageList_Destroy() retval=00000001 ret=005027f5 ...
Then LISTVIEW_NCDestroy is called.
trace:listview:LISTVIEW_NCDestroy () trace:listview:LISTVIEW_DeleteAllItems () trace:commctrl:DPA_DeleteAllPtrs (0x41690d98) ... trace:listview:notify_hdr <= 0 trace:listview:LISTVIEW_NCDestroy Start destroying data structures. ...
The listview does not know that the imagelist was already destroyed, so it again calls ImageList_Destroy.
trace:listview:LISTVIEW_NCDestroy Start destroying image lists. 08073208:Call gdi32.DeleteObject(aaaaaaaa) ret=409fcadd 08073208:Ret gdi32.DeleteObject() retval=00000000 ret=409fcadd 08073208:Call gdi32.DeleteObject(aaaaaaaa) ret=409fcaea 08073208:Ret gdi32.DeleteObject() retval=00000000 ret=409fcaea 08073208:Call gdi32.DeleteObject(aaaaaaaa) ret=409fcaf7 08073208:Ret gdi32.DeleteObject() retval=00000000 ret=409fcaf7 08073208:Call gdi32.DeleteObject(aaaaaaaa) ret=409fcb04 08073208:Ret gdi32.DeleteObject() retval=00000000 ret=409fcb04
At the end of ImageList_Destroy, there is a call to ZeroMemory, which obliterates the prev and next pointers which had been written there. Then another COMCTL32_Free call detects the error. At least I assume it is an error.
trace:commctrl:COMCTL32_Free (0x41691ba0) err:heap:HEAP_ValidateFreeArena Heap 41690000: bad next ptr 00000000 for arena 41691b98
Duane Clark wrote:
... At the end of ImageList_Destroy, there is a call to ZeroMemory, which obliterates the prev and next pointers which had been written there. Then another COMCTL32_Free call detects the error. At least I assume it is an error.
And indeed simply commenting out the ZeroMemory fixes the application. Though I have no idea what the correct fix would be.
On December 22, 2002 02:50 pm, Duane Clark wrote:
That area is then freed. When freed, COMCTL32_Free writes prev and next entries into himl.
Where? COMCTL32_Free() simply calls HeapFree():
BOOL WINAPI COMCTL32_Free (LPVOID lpMem) { TRACE("(%p)\n", lpMem); return HeapFree (COMCTL32_hHeap, 0, lpMem); }
The listview does not know that the imagelist was already destroyed, so it again calls ImageList_Destroy.
Yes, a common problem.
At the end of ImageList_Destroy, there is a call to ZeroMemory, which obliterates the prev and next pointers which had been written there. Then another COMCTL32_Free call detects the error. At least I assume it is an error.
Does this work any better? It shouldn't make any difference, but ...
There is something else funny here. I can't see why zeroing out an area we're just about to free is problematic.
Index: dlls/comctl32/imagelist.c =================================================================== RCS file: /var/cvs/wine/dlls/comctl32/imagelist.c,v retrieving revision 1.68 diff -u -r1.68 imagelist.c --- dlls/comctl32/imagelist.c 5 Dec 2002 20:33:09 -0000 1.68 +++ dlls/comctl32/imagelist.c 23 Dec 2002 04:37:55 -0000 @@ -693,7 +693,7 @@ if (himl->hbrBlend50) DeleteObject (himl->hbrBlend50);
- ZeroMemory(himl, sizeof(*himl)); + ZeroMemory(himl, sizeof(struct _IMAGELIST)); COMCTL32_Free (himl);
return TRUE;