Thread: Crash on WM_PAINT message

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    34

    Question Crash on WM_PAINT message

    Hi,

    I've been left somewhat puzzeled with my program crashing when WM_PAINT is sent to my custom control. It is the memory protection that is bombing out.


    I create my custom control and supply the size of a pointer to my custom control structure like this:
    Code:
    wc.cbWndExtra = sizeof(CustomCtrl *);
    Before registering it.

    For retrieving the pointer to the custom control I have this function:
    Code:
    CustomCtrl * GetCustomCtrl(HWND hwnd) {
        return (CustomCtrl *)GetWindowLong(hwnd, 0);
    }
    And for setting the pointer i have:
    Code:
    void SetCustomCtrl(HWND hwnd, CustomCtrl *ccp) {
        SetWindowLong(hwnd, 0, (LONG)ccp);
    }

    In my window procedure I have:
    Code:
    CustCtrl *ccp = GetCustomCtrl(hwnd);
    And during the handling of the WM_NCCREATE message I am allocating memory for the custom control structure and initializing it. Then I call:
    Code:
    SetCustomCtrl(hwnd, ccp);
    To store the pointer to my structure in the window datastructure.

    Now, in my WM_CREATE handler I have no problems accessing the members of the structure.

    But, however, when I am about to handle the WM_PAINT message, the code crashes.

    One of my crash reports:
    Exception 0xc0000005 occurred at location 0x06634935 at time Wed Mar 11 09:46:12 2009

    (Reading inaccessible data at address 0x00000014)
    As far as I can tell by looking at this, it would seem like the pointer to ccp is invalid, hence the attempt to access 0x00000014. There have also been other attemts to access 0x00000004 and 0x00000008, dpending og which member of the structure I am trying to access.

    A dump of the stack and CPU registers:
    *----> State Dump <----*
    EAX=40010d29 EBX=40010d29 ECX=00010c8c EDX=7c90eb94 ESI=00000004
    EDI=0000000f EIP=06634935 ESP=0903fcd8 EBP=0903fdac FLAGS=00010246
    CS=001b SS=0023 DS=0023 FS=003b GS=0000

    *----> Stack Back Trace <----*
    FramePtr ReturnAd Param#1 Param#2 Param#3 Param#4
    0903fdac 7e418734 008a0292 0000000f 00000000 00000000
    0903fdd8 7e418816 06634880 008a0292 0000000f 00000000
    0903fe40 7e41b4c0 00000000 06634880 008a0292 0000000f
    0903fe94 7e41b50c 008af618 0000000f 00000000 00000000
    0903febc 7c90eae3 0903fecc 00000018 008af618 0000000f
    0903fef4 0663a045 00d20066 0000000a 00d20066 00cf0000
    0903ff34 06633335 066412d0 00400000 0000000a 06630000
    0903ff94 0663a822 00400000 00000000 00000000 00000005
    0903ffb4 7c80b683 00000000 00000000 00000000 00000000

    *----> Raw Stack Dump <----*
    0903fcd8 34 FD 03 09 64 00 00 00 19 00 00 00 E8 C2 B5 00 4...d...........
    0903fce8 14 FD 03 09 29 B6 41 7E 95 23 63 06 AA 01 78 00 ......A...c...x.
    0903fcf8 24 FD 03 09 FF FF FF FF 14 FD 03 09 00 00 00 00 ................
    0903fd08 24 FD 03 09 66 00 00 00 1F 05 01 BA 04 00 00 00 ....f...........
    0903fd18 03 00 00 00 64 00 00 00 00 00 01 00 64 0B 01 6A ....d.......d..j
    0903fd28 00 00 00 00 00 00 00 00 00 00 00 00 1F 05 01 BA ................
    0903fd38 00 00 00 00 00 00 00 00 00 00 00 00 3C 00 00 00 ................
    0903fd48 50 00 00 00 00 00 00 00 00 00 00 00 64 0B 01 6A P...........d..j
    0903fd58 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00 00 ................
    0903fd68 BE 00 00 00 00 00 00 00 00 00 00 00 E8 C2 B5 00 ................
    0903fd78 AA 01 78 00 AC FD 03 09 92 31 63 06 E8 C2 B5 00 ..x......1c.....
    0903fd88 00 00 00 00 B0 2E 63 06 00 00 00 00 00 00 00 00 ......c.........
    0903fd98 00 00 00 00 00 00 00 00 00 00 00 00 80 48 63 06 .............Hc.
    0903fda8 14 FE 03 09 D8 FD 03 09 34 87 41 7E 92 02 8A 00 ........4.A.....
    0903fdb8 0F 00 00 00 00 00 00 00 00 00 00 00 80 48 63 06 .............Hc.
    0903fdc8 CD AB BA DC 00 00 00 00 14 FE 03 09 80 48 63 06 .............Hc.
    0903fdd8 40 FE 03 09 16 88 41 7E 80 48 63 06 92 02 8A 00 ......A..Hc.....
    0903fde8 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    0903fdf8 92 02 8A 00 D0 12 64 06 14 00 00 00 01 00 00 00 ......d.........
    0903fe08 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 ................

    *----> Raw Stack Dump LONG HEX <----*
    0903fcd8 0x0903fd34 0x00000064 0x00000019 0x00b5c2e8 RW .. .. RW
    0903fce8 0x0903fd14 0x7e41b629 0x06632395 0x007801aa RW R. R. R.
    0903fcf8 0x0903fd24 0xffffffff 0x0903fd14 0x00000000 RW .. RW ..
    0903fd08 0x0903fd24 0x00000066 0xba01051f 0x00000004 RW .. .. ..
    0903fd18 0x00000003 0x00000064 0x00010000 0x6a010b64 .. .. RW ..
    0903fd28 0x00000000 0x00000000 0x00000000 0xba01051f .. .. .. ..
    0903fd38 0x00000000 0x00000000 0x00000000 0x0000003c .. .. .. ..
    0903fd48 0x00000050 0x00000000 0x00000000 0x6a010b64 .. .. .. ..
    0903fd58 0x00000000 0x00000000 0x00000000 0x00000104 .. .. .. ..
    0903fd68 0x000000be 0x00000000 0x00000000 0x00b5c2e8 .. .. .. RW
    0903fd78 0x007801aa 0x0903fdac 0x06633192 0x00b5c2e8 R. RW R. RW
    0903fd88 0x00000000 0x06632eb0 0x00000000 0x00000000 .. R. .. ..
    0903fd98 0x00000000 0x00000000 0x00000000 0x06634880 .. .. .. R.
    0903fda8 0x0903fe14 0x0903fdd8 0x7e418734 0x008a0292 RW RW R. R.
    0903fdb8 0x0000000f 0x00000000 0x00000000 0x06634880 .. .. .. R.
    0903fdc8 0xdcbaabcd 0x00000000 0x0903fe14 0x06634880 .. .. RW R.
    0903fdd8 0x0903fe40 0x7e418816 0x06634880 0x008a0292 RW R. R. R.
    0903fde8 0x0000000f 0x00000000 0x00000000 0x00000000 .. .. .. ..
    0903fdf8 0x008a0292 0x066412d0 0x00000014 0x00000001 R. RW .. ..
    0903fe08 0x00000000 0x00000000 0x00000010 0x00000000 .. .. .. ..
    0903fe18 0x00000000 0x00000000 0x00000000 0x00000000 .. .. .. ..
    0903fe28 0x0903fdf4 0x0903f8fc 0x0903fe84 0x7e440457 RW RW RW R.
    0903fe38 0x7e418830 0x00000000 0x0903fe94 0x7e41b4c0 R. .. RW R.
    0903fe48 0x00000000 0x06634880 0x008a0292 0x0000000f .. R. R. ..
    0903fe58 0x00000000 0x00000000 0x008af62c 0x00000001 .. .. R. ..
    0903fe68 0x00000000 0x00000000 0x066412d0 0x7e41b4cb .. .. RW R.
    0903fe78 0x00000000 0x0903fe68 0x0903f8fc 0x0903ffdc .. RW RW RW
    0903fe88 0x7e440457 0x7e41b4d0 0xffffffff 0x0903febc R. R. .. RW
    0903fe98 0x7e41b50c 0x008af618 0x0000000f 0x00000000 R. R. .. ..
    0903fea8 0x00000000 0x06634880 0x00000001 0x00000000 .. R. .. ..
    0903feb8 0x00000000 0x0903fef4 0x7c90eae3 0x0903fecc .. RW R. RW
    0903fec8 0x00000018 0x008af618 0x0000000f 0x00000000 .. R. .. ..
    0903fed8 0x00000000 0x06634880 0x7e41b473 0x7e41d83f .. R. R. R.
    0903fee8 0x7e41d82a 0x00d20066 0x0000005e 0x0903ff34 R. RW .. RW
    0903fef8 0x0663a045 0x00d20066 0x0000000a 0x00d20066 R. RW .. RW
    0903ff08 0x00cf0000 0x000000c8 0x000000c8 0x0000010e RW .. .. ..
    0903ff18 0x000000dc 0x00000000 0x00000000 0x00400000 .. .. .. R.
    0903ff28 0x00000000 0x06630000 0x00400000 0x0903ff94 .. R. R. RW
    0903ff38 0x06633335 0x066412d0 0x00400000 0x0000000a R. RW R. ..
    0903ff48 0x06630000 0x80502592 0x00000000 0x00000005 R. .. .. ..
    How I launch this thing may or may not be the reason. Basically I am doing this:

    I call a DLL from another application, which spawns a new win32 thread and returns.
    The new thread opens a window, which creates some custom controls. Among those, is this one that is giving me trouble.

    I have made three (3) other custom controls using the excact same method as with this one. All of them are working fine.

    Does anyone have any idea what is failing and how to solve this?

    Thanks,
    Eirik

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The error you get is clearly a NULL-pointer access.

    Where are you seeting the value passed to SetWindowLong()?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    34
    The error you get is clearly a NULL-pointer access.
    Yeah, that was my thought too. I just couldn't figure out why it only happened during my WM_PAINT message.

    Where are you seeting the value passed to SetWindowLong()?
    I am setting it during the WM_NCCREATE message. Like this:

    Code:
            case WM_NCCREATE:
                ccp = (CustomCtrl *)malloc(sizeof(CustomCtrl));
    
                if(ccp == NULL) {
                    MessageBox(NULL,"Failed to allocate memory","Crap",MB_OK|MB_ICONERROR);
                    return FALSE;
                }
    
                ccp->hwnd       = hwnd;
                ccp->hwndParent = GetParent(hwnd);
                ccp->wStates    = 0x0000;
    
                SetCustomCtrl(hwnd, ccp);
    
                return TRUE;
    As I understand this, even if the activation frame for my callback function ceases to exist, the pointer to my structure is still valid. I don't free up the ccp memory before I recieve a WM_DESTROY message.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Unfortunately, the cause of your problem is almost certainly in code executed before you see symptoms. A basic rule of nature is that a crash occurs after the root cause, but there is no requirement that it occur immediately.

    My guess would be that some seemingly unrelated code is molesting a pointer - possibly before the WM_PAINT message is even dispatched. That pointer molestation happens to mess up some data structure used internally by the malloc() function, so it happens that the problem is first detected when you dereference cpp (which contains a return value from malloc()).

    Which means you need to look in code executed before - possibly significantly before - the crash actually occurs.

  5. #5
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,130
    Why do you malloc memory for something that obviously is a class or struct and therefore should have a constructor which you circumvent? Why don't you just say "new CustomCtrl()" ? And why do you put the size of a pointer somewhere? Size of a pointer will always be 4 (on 32bit systems) so you either save something meaningless, or you save the wrong value... try to check that line and find out why you are supposed to put something meaningless there.
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    34
    @grumpy

    My guess would be that some seemingly unrelated code is molesting a pointer - possibly before the WM_PAINT message is even dispatched. That pointer molestation happens to mess up some data structure used internally by the malloc() function, so it happens that the problem is first detected when you dereference cpp (which contains a return value from malloc()).
    Yeah, I saved out the pointer value during WM_PAINT, to invesigate its value, and I found it to be 0x4. I'll do some (further) thorough investigation of my code and see if I can track down what is molesting it.

    @nvogit

    Why do you malloc memory for something that obviously is a class or struct and therefore should have a constructor which you circumvent? Why don't you just say "new CustomCtrl()" ?
    This is not C++

    And why do you put the size of a pointer somewhere?
    I reserve space in the window class structure for a pointer to my custom structure, so that I am able to retrieve it by using GetWindowLong() for each instance of the control created.

    Size of a pointer will always be 4 (on 32bit systems)
    Yes, hence the sizeof(CustCtrl*). If the code was to be migrated to a 64-bit system, then it would only need a recompile...

    try to check that line and find out why you are supposed to put something meaningless there.
    I would imagine I am supposed to put something meaningfull there, but I get your point :-)

  7. #7
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> This is not C++
    No need to cast malloc then.

    >> SetWindowLong(hwnd, 0, (LONG)ccp);
    2 things: Use SetWindowLongPtr(). Use GWLP_USERDATA for the index, not 0.

    >> If the code was to be migrated to a 64-bit system, then it would only need a recompile...
    But it wouldn't work - due to that LONG cast and not using SetWindowLongPtr()

    gg

  8. #8
    Registered User
    Join Date
    Oct 2008
    Posts
    34
    @Codeplug

    Ah, you are absolutely right.. :-)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange string behavior
    By jcafaro10 in forum C Programming
    Replies: 2
    Last Post: 04-07-2009, 07:38 PM
  2. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  3. Making a script language?
    By Blackroot in forum Game Programming
    Replies: 10
    Last Post: 02-16-2006, 02:22 AM
  4. Dialog Box Problems
    By Morgul in forum Windows Programming
    Replies: 21
    Last Post: 05-31-2005, 05:48 PM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM