0

I am getting a memory exception in (unchanged) code that has been working for 2+ years (code is unchanged, in a Git repo).

Here's the code that is causing the exception:

HTREEITEM getTreeNode(HWND hDlg, char *name, HTREEITEM parent)
{
    TV_INSERTSTRUCT tvinsert = {};
    tvinsert.hParent = parent;
    tvinsert.hInsertAfter = parent ? TVI_SORT : TVI_ROOT;
    tvinsert.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
    tvinsert.item.pszText = name;
    tvinsert.item.lParam = -1;
    tvinsert.item.iImage = 0;
    tvinsert.item.iSelectedImage = 1;

    if (IsWindow(hDlg))
        LogError("**** window ok");
    else
        LogError("**** Window issue....");

    HWND presetHDlg = GetDlgItem(hDlg, IDC_PRESET_TREE);
    if (IsWindow(presetHDlg))
        LogError("**** Preset Tree window ok");
    else
        LogError("**** Preset Tree Window issue....");

    HTREEITEM newNode = (HTREEITEM)SendDlgItemMessage(hDlg, IDC_PRESET_TREE,
        TVM_INSERTITEM, 0, (LPARAM)&tvinsert);
    if (nodes == NULL)
    { ...

The exception occurs when calling SendDlgItemMessage(), and both IsWindow() calls return TRUE. Prior to calling this function, another call to SendDlgItemMessage() to the same control, to set the bitmap/image list, works without an issue:

void addPresetsTree(HWND hDlg)
{

// Load bitmaps used in tree view
HIMAGELIST hImageList = ImageList_Create(16, 16, ILC_COLOR16, 2, 10);
HBITMAP hBitMap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_OPEN_FOLDER));
if (hBitMap == NULL) LogError("*** Failed to load bitmap for IDB_OPEN_FOLDER");
else
{
    ImageList_Add(hImageList, hBitMap, NULL);
    DeleteObject(hBitMap);
}
hBitMap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_CLOSED_FOLDER));
if (hBitMap == NULL) LogError("*** Failed to load bitmap for IDB_CLOSED_FOLDER");
else
{
    ImageList_Add(hImageList, hBitMap, NULL);
    DeleteObject(hBitMap);
}
hBitMap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_PRESET));
if (hBitMap == NULL) LogError("*** Failed to load bitmap for IDB_PRESET");
else
{
    ImageList_Add(hImageList, hBitMap, NULL);
    DeleteObject(hBitMap);
}
hBitMap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SELECTED_PRESET));
if (hBitMap == NULL) LogError("*** Failed to load bitmap for IDB_SELECTED_PRESET");
else
{
    ImageList_Add(hImageList, hBitMap, NULL);
    DeleteObject(hBitMap);
}
LRESULT res = SendDlgItemMessage(hDlg, IDC_PRESET_TREE, TVM_SETIMAGELIST, 0, (LPARAM)hImageList);
    HTREEITEM Parent = NULL;
char p[] = "RootNode";
Parent = getTreeNode(hDlg, p, Parent);
}

This code is called on receiving the WM_INITDIALOG message in the dialog proc:

BOOL CALLBACK FindPresetDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_INITDIALOG:
            InitCommonControls();     // make our tree control work
            // Populate preset tree and select current entry, if available
            addPresetsTree(hDlg);
            break;
    ...

The strange thing is that this code has been working for several years, and I only noticed this exception in June this year (last working build I have is from April). I keep my source under Git, and all old version releases, previously all working, now give this exception.

The stack trace shows the following Windows DLL modules are called:

KernelBase.dll!MultiByteToWideChar()
comctl32.dll!ProduceWFromA()
comctl32.dll!TV_InsertItemA(struct _TREE *,struct tagTVINSERTSTRUCTA *)
comctl32.dll!TV_WndProc(struct HWND__ *,unsigned int,unsigned __int64,__int64)
user32.dll!UserCallWinProcCheckWow(struct _ACTIVATION_CONTEXT *,__int64 (*)(struct tagWND *,unsigned int,unsigned __int64,__int64),struct HWND__ *,enum _WM_VALUE,unsigned __int64,__int64,void *,int)
user32.dll!SendMessageWorker()
user32.dll!SendMessageInternal(struct HWND__ *,unsigned int,unsigned __int64,__int64,int)
user32.dll!SendMessageA()
user32.dll!SendDlgItemMessageA()
FSUIPC7.exe!getTreeNode(HWND__ * hDlg, char * name, _TREEITEM * parent) Line 76
    at E:\Repos\MyApp\MyApp\FindPreset.cpp(76)
MyApp.exe!addPresetsTree(HWND__ * hDlg) Line 151
    at E:\Repos\MyApp\MyApp\FindPreset.cpp(151)
MyApp.exe!FindPresetDlgProc(HWND__ * hDlg, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 216
    at E:\Repos\MyApp\MyApp\FindPreset.cpp(216)
    

I can only assume that this exception must be due to either a change in one of those Windows DLLs, or maybe due to a change/update of Visual Studio 2022.

I have also tried creating a minimal app to show the issue, using the same code, but I get no exception in this app - it works just fine.

Note that I also had a catastrophic failure caused by a Windows Insider update shortly after discovering this issue, and I have had to completely re-install Windows 11 (no backup!). This error is still present, but I have no history of any Windows or Visual Studio updates. All I can know is that the last working version of this app was built on April 9th 2025, and every build after this has this error.

I'm not sure what I can do now to determine what is causing this exception - does anyone have any ideas on what could cause this, or what I can do to track this down?

Here's the GitHub Copilot report (for what it's worth!):

The exception is an access violation (0xC0000005) caused by attempting to read from an invalid memory location (0x00000000000000E4). The immediate cause is the SendDlgItemMessage call in the getTreeNode function, which attempts to interact with a tree view control (IDC_PRESET_TREE) using an invalid or uninitialized HWND (presetHDlg).

Root Cause:

  1. Invalid HWND: The GetDlgItem call to retrieve IDC_PRESET_TREE returns an invalid handle (presetHDlg), likely because hDlg is not a valid dialog handle or the control does not exist.

  2. Uninitialized or Corrupted Data: The hDlg parameter passed to getTreeNode might be uninitialized or corrupted, leading to invalid operations.

Suggested Fix:

• Validate hDlg before calling GetDlgItem. Ensure hDlg is a valid dialog handle.

• Check if IDC_PRESET_TREE exists in the dialog resource.

34
  • 2
    char comment[256]; - That's UB if you're ever accessing it without initializing it. Since we can't see the use, please show a minimal reproducible example. Commented Jun 30 at 13:35
  • 1
    Why are you incrementing noTreeNodes before a new node is actually created? If something goes wrong, you risk accessing invalid nodes entries at a later time. Also, on a side note, since you already have the TreeView HWND from GetDlgItem(), you should use SendMessage() instead of SendDlgItemMessage(). Commented Jun 30 at 15:29
  • 1
    Also, the AV error message says the AV occurred accessing address 0x00000000000000E4, which is very close to 0x0000000000000000, suggesting an object member or array element is being accessed via a NULL pointer. Sending a window message to a NULL HWND is safe (the send will just fail with an error code), so the affected pointer has to be somewhere else. 0xE4 is 228 (unsigned) or -28 (signed), do those values mean anything to you? Commented Jun 30 at 15:34
  • 1
    "it HAS been working for several years" - The wording is rather presumptuous. If your goal is to solve the issue, you should rather think of it as: "This hasn't FAILED yet." Regardless, if a piece of code isn't relevant to the problem, remove it (such as the comment array). "If something goes wrong it will CTD" - I don't know what "CTD" means, but it sounds like you are assuming that any sort of "undefined behavior" would necessarily have to materialize predictably. This assumption has no ground. Commented Jun 30 at 19:28
  • 2
    Also, if you want to understand the specifics of this failure, make sure to load public debug symbols into your debugger. The stack trace is of little use as posted. Commented Jun 30 at 19:32

1 Answer 1

-1

This issue/exception was caused by the inclusion of a header file called wsipx2.h which has the following header:

/*       WSIPX.H -- Winsock 2 Extensions for IPX networks
 *
 *  This file contains IPX/SPX specific information for use by
 *  Winsock 2 comparable applications.  Include this file below
 *  WINSOCK.H to enable IPX features in your application.
 *
 *                   Rev 0.3, Feb 23, 1995  
 */

This header changed the packing to 1 but does not reset it, which I presume is the root cause. I am not sure why this file is included, and suspect the packing change was added many years ago by the original author of this program.

I have removed this header file and all is now good.

One thing still puzzles me though: the code hasn't changed for many years, and only recently started causing this issue with no code change and no other change that I can think of (although there were VS and OS updates, a friend verified on a lot older version of both and the error/exception was still present.

Sign up to request clarification or add additional context in comments.

10 Comments

This does not explain why a compiler update surfaced the issue.
Why do you think a compiler update? I suspect it was a windows update (or toolkit) in the Commctrl.dll, but I am also puzzled by this.
Random shot but I also maintain an old app that's started having problems related to image lists and comctl32 in recent months after working for years - potentially MS has been messing with something that's breaking old apps. stackoverflow.com/questions/79708990/…
Thats interesting. My issue was due to packing, but was certainly provoked by an MS update of one sort or the other.
And also, but with respect - I see you are highly rated and a valued contributor, I think you should be more careful with your UB BS that ignores the problem at hand. Even though the code is not perfect, it causes no issues and all your comments were just a distraction from the issue at hand. You asked the wrong questions. See the other thread where the contributions were actually helpful.
"Why do you think a compiler update?" - Because a system update doesn't cause these sorts of issues. "I think you should be more careful with your UB BS" - Here's the 101 on compilers: A compiler update cannot change the observable behavior of a correct program. Conversely, if a compiler update changes the observable behavior, it's guaranteed that the program is invalid. "See the other thread where the contributions were actually helpful." - Oh, you mean where they suggested that you hook system calls instead of setting a breakpoint in your debugger? Yeah, that's really helpful...
Yes, invalid due to packing issues. There was obviously an issue in the code due to this that went unnoticed for many years as there were no obvious problems, but a system toolkit change then provoked this exception. Of course I used breakpoints in the debugger - did you not see the info I posted on these? They did not reveal much. The hook was useful (as well as other recommendations in that thread) in determining that it was actually a packing issue and not memory corruption elsewhere. And with that, I'm finished here. Have a good day.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.