Hi,
Agent 2.0 beta crashes on listview related code, and requires native comctl32 to run.
Here is a cut from a +relay,+message,+listview trace:
| trace:message:SPY_ExitMessage (0x1004b) L"{SysListView32}" message [1004] LVM_GETITEMCOUNT returned 00000000 | 0009:Ret user32.SendMessageA() retval=00000000 ret=005cad80
At this point the listview is newly created, headers column inserted etc. No items yet.
| 0009:Call user32.SendMessageA(0001004b,00001007,00000000,406cf6f8) ret=005cc1b4 | trace:message:SPY_EnterMessage (0x1004b) L"{SysListView32}" message [1007] LVM_INSERTITEMA sent from self wp=00000000 lp=406cf6f8 | trace:message:SPY_DumpMem LVITEM [0000] 00000003 00000000 00000000 00000000 | trace:message:SPY_DumpMem LVITEM [0010] 00000000 42103914 00000018 ffffffff | trace:message:SPY_DumpMem LVITEM [0020] 61737365 005cc11f 406cf770 006b30b6 | trace:message:SPY_DumpMem LVITEM [0030] ffffffff
The program inserts the first item. Valid fields are Text and Image.
| trace:listview:LISTVIEW_WindowProc (uMsg=1007 wParam=0 lParam=406cf6f8)
| trace:listview:LISTVIEW_InsertItemT (lpLVItem={iItem=0, iSubItem=0, pszText="application/octet-stream", cchTextMax=24, iImage=-1}, isW=0)
| trace:listview:LISTVIEW_InsertItemT inserting at 0, sorted=1, count=0, iItem=0 | trace:listview:LISTVIEW_ShiftIndices Shifting 0u, 1 steps | trace:listview:set_main_item () | trace:listview:set_main_item oldState=0, newState=0 | trace:listview:set_main_item uChanged=0x3 | trace:listview:notify_listview (code=-102, plvnm=iItem=0, iSubItem=0, uNewState=0x0, uOldState=0x0, uChanged=0x0, ptAction=(0, 0), lParam=0 )
| trace:listview:notify_hdr (code=-102)
| trace:message:SPY_EnterMessage (0x10049) L"{wxWindowClass}" message [004e] WM_NOTIFY sent from self wp=00001e68 lp=406cf148 | trace:message:SPY_DumpStructure NMHDR hwndFrom=0x1004b idFrom=0x00001e68 code=LVN_INSERTITEM<0xffffff9a>, extra=0x20 | trace:message:SPY_DumpMem NM extra [0000] 00000000 00000000 00000000 00000000 | trace:message:SPY_DumpMem NM extra [0010] 00000000 00000000 00000000 00000000
Still inside the LVM_ISERTITEMA message a WM_NOTIFY is sent. The programs message handler queries number of items:
| 0009:Call user32.SendMessageA(0001004b,00001004,00000000,00000000) ret=005cad80 | trace:message:SPY_EnterMessage (0x1004b) L"{SysListView32}" message [1004] LVM_GETITEMCOUNT sent from self wp=00000000 lp=00000000 | trace:listview:LISTVIEW_WindowProc (uMsg=1004 wParam=0 lParam=0) | trace:message:SPY_ExitMessage (0x1004b) L"{SysListView32}" message [1004] LVM_GETITEMCOUNT returned 00000001 | 0009:Ret user32.SendMessageA() retval=00000001 ret=005cad80
there is one item.
| 0009:Call user32.SendMessageA(0001004b,00001005,00000000,406cebe0) ret=005ca4cb | trace:message:SPY_EnterMessage (0x1004b) L"{SysListView32}" message [1005] LVM_GETITEMA sent from self wp=00000000 lp=406cebe0 | trace:message:SPY_DumpMem LVITEM [0000] 00000004 00000000 42100a50 406cf148 | trace:message:SPY_DumpMem LVITEM [0010] 406cf154 406ced10 407c1c09 005cad80 | trace:message:SPY_DumpMem LVITEM [0020] 0001004b 00001004 406ced10 005ccb9a | trace:message:SPY_DumpMem LVITEM [0030] 0001004b
and request that lParam of that item. Note that iItem is zero but iSubItem is 0x42100a50, like all other fields it is filled with rubbish. (confirmed with dissassembly that only the mask and iItem fields are filled in)
| trace:listview:LISTVIEW_WindowProc (uMsg=1005 wParam=0 lParam=406cebe0) | trace:listview:LISTVIEW_GetItemT (lpLVItem={iItem=0, iSubItem=1108347472, lParam=1004b}, isW=0) | trace:message:SPY_ExitMessage (0x1004b) L"{SysListView32}" message [1005] LVM_GETITEMA returned 00000001 | trace:message:SPY_DumpMem LVITEM [0000] 00000004 00000000 42100a50 406cf148 | trace:message:SPY_DumpMem LVITEM [0010] 406cf154 406ced10 407c1c09 005cad80 | trace:message:SPY_DumpMem LVITEM [0020] 0001004b 00001004 406ced10 005ccb9a | trace:message:SPY_DumpMem LVITEM [0030] 0001004b
At return, the requested value of lParam is still rubbish, which is causing a crash somewhat later.
| trace:message:SPY_ExitMessage (0x10049) L"{wxWindowClass}" message [004e] WM_NOTIFY returned 00000000 | trace:message:SPY_DumpStructure NMHDR hwndFrom=0x1004b idFrom=0x00001e68 code=LVN_INSERTITEM<0xffffff9a>, extra=0x20 | trace:message:SPY_DumpMem NM extra [0000] 00000000 00000000 00000000 00000000 | trace:message:SPY_DumpMem NM extra [0010] 00000000 00000000 00000000 00000000 | 0009:Ret user32.SendMessageW() retval=00000000 ret=40b49738
If I hack LISTVIEW_GetItemT() with a hack like:
| | if (lpSubItem) | { | SUBITEM_INFO *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, lpLVItem->iSubItem); | pItemHdr = lpSubItem ? &lpSubItem->hdr : &callbackHdr; |+ if(!lpSubItem) lpLVItem->iSubItem = 0; | }
the program proceeds (crashes much much later) . But this is probably not the correct way to check that an invalid subitem has been passed (for instance I don't understand the callbackHdr stuff above).
Any suggestion what is the correct fix?
Full log at www.xs4all.nl/~rklazes/temp/agent.log.bz2
Rein.
On November 12, 2003 08:30 am, Rein Klazes wrote:
| if (lpSubItem) | { | SUBITEM_INFO *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, | lpLVItem->iSubItem); pItemHdr = lpSubItem ? &lpSubItem->hdr : | &callbackHdr; |+ if(!lpSubItem) lpLVItem->iSubItem = 0; | }
the program proceeds (crashes much much later) . But this is probably not the correct way to check that an invalid subitem has been passed (for instance I don't understand the callbackHdr stuff above).
Any suggestion what is the correct fix?
OK, I've looked at the code, and it may be the fix. The problem with it is that we modify the app's structure, which may be a problem. Can you please check with the native comctl32 if it modifies iSubItem to 0 after the call?
On Sat, 15 Nov 2003 01:50:34 -0500, you wrote:
On November 12, 2003 08:30 am, Rein Klazes wrote:
| if (lpSubItem) | { | SUBITEM_INFO *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, | lpLVItem->iSubItem); pItemHdr = lpSubItem ? &lpSubItem->hdr : | &callbackHdr; |+ if(!lpSubItem) lpLVItem->iSubItem = 0; | }
the program proceeds (crashes much much later) . But this is probably not the correct way to check that an invalid subitem has been passed (for instance I don't understand the callbackHdr stuff above).
Any suggestion what is the correct fix?
OK, I've looked at the code, and it may be the fix. The problem with it is that we modify the app's structure, which may be a problem. Can you please check with the native comctl32 if it modifies iSubItem to 0 after the call?
I forgot to mention exactly that, it does not. It is just my application that happens not to use it.
Rein.
On Sat, 15 Nov 2003 01:50:34 -0500, you wrote:
On November 12, 2003 08:30 am, Rei
OK, I've looked at the code, and it may be the fix. The problem with it is that we modify the app's structure, which may be a problem. Can you please check with the native comctl32 if it modifies iSubItem to 0 after the call?
OK, here is a patch that doesn't modify the structure.
Changelog: dlls/comctl32 : listview.c Ignore invalid iSubItem in LISTVIEW_GetItemT()
Rein.
On November 15, 2003 09:43 am, Rein Klazes wrote:
OK, this looks good, but 2 small nits:
dispInfo.item.iSubItem = lpLVItem->iSubItem;
dispInfo.item.iSubItem = isubitem;
I'm not sure if we have to use the original one here or not. We should add a test for this mess as well...
if( !lpSubItem) {
WARN(" iSubItem invalid (%08x), ignored.\n", isubitem);
isubitem = 0;
}
Please use the same braketing style as the rest of the code. Also, I'm not sure this is a WARN, if this is actual behaviour, maybe a TRACE would be better.
On Sat, 15 Nov 2003 10:56:34 -0500, you wrote:
On November 15, 2003 09:43 am, Rein Klazes wrote:
OK, this looks good, but 2 small nits:
dispInfo.item.iSubItem = lpLVItem->iSubItem;
dispInfo.item.iSubItem = isubitem;
I'm not sure if we have to use the original one here or not. We should add a test for this mess as well...
I will see how to figure this one out.
if( !lpSubItem) {
WARN(" iSubItem invalid (%08x), ignored.\n", isubitem);
isubitem = 0;
}
Please use the same braketing style as the rest of the code.
Oops, didn't see that. I will fix it.
Also, I'm not sure this is a WARN, if this is actual behaviour, maybe a TRACE would be better.
I now think this is an error in the application. If I understand it well, that if the random entry for iSubItem happens by chance to be valid, the application must get something else then it thought it asked for. The makers agree and are willing to fix these instances in Agent, three places until sofar. But I will run the beta's with listview+warn to check for more.
Rein.