The Old New Thing's Journal
 
[Most Recent Entries] [Calendar View] [Friends View]

Thursday, December 26th, 2013

    Time Event
    3:00p
    Why is GetWindowLongPtr returning a garbage value on 64-bit Windows?

    A customer was running into problems with their application on 64-bit Windows 8. They claimed that on Windows 8, the Get­Window­Long­Ptr is returning a garbage pointer, which causes their program to crash. The same program works fine on 64-bit Windows 7. They asked the Windows team why they broke Get­Window­Long­Ptr.

    An investigation of the customer's code quickly turned up the issue:

    INT_PTR CALLBACK AwesomeDialogProc(
        HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
      Awesome *pThis = (Awesome*)GetWindowLongPtr(hdlg, DWLP_USER);
    
      switch (uMsg) {
      case WM_INITDIALOG:
        pThis = (Awesome*)lParam;
        SetWindowLongPtr(hdlg, DWLP_USER, (LONG)pThis);
        ...
        return TRUE;
    
       case WM_COMMAND:
         if (pThis != nullptr) {
           // This line crashes with pThis = garbage nonzero value
           return pThis->OnCommand(wParam, lParam);
         }
         return FALSE;
    
       ...
      }
      return FALSE;
    }
    

    See if you can spot the problem.

    The error is in the line that calls Set­Window­Long­Ptr. It takes the 64-bit pointer value pThis and casts it to a LONG, which is a 32-bit integer type. This truncates the pointer and throws away the upper 32 bits of data. Therefore, when read back, the pointer looks like garbage because the top 32 bits were set to zero (or to 0xFFFFFFFF, depending on the value of bit 31).

    Windows 8 made some improvements to the memory manager, and a side effect was a seemingly harmless change to the way memory is allocated in 64-bit processes. As a result of the change, pointer values greater than 4GB are much more common, which means that the pointer truncation will actually destroy data. (In Windows 7, the default heap tended to hang out below the 2GB boundary, so the code merely truncated zeros, which is mostly harmless.)

    What I found particularly interesting about this error is that the DWL_USER window long was specifically renamed to DWLP_USER in 64-bit Windows in order to force a build break. Therefore, developers had to go in and convert each separate use of [GS]et­Window­Long with DWL_USER to a version that used [GS]et­Window­Long­Ptr with DWLP_USER, being careful not to truncate the pointer.

    This customer missed that last little bit about not truncating the pointer, and all they did was a global search/replace:

    s/\bGetWindowLong\b/GetWindowLongPtr/g;
    s/\bSetWindowLong\b/SetWindowLongPtr/g;
    s/\bDWL_USER\b/DWLP_USER/g;
    

    "There, I fixed it."

    3:00p
    I think we're going to be getting frozen leftovers for lunch today

    There are a few times a year when a large fraction of employees are out on vacation at the same time, such as a single work day wedged between a holiday and a weekend (as happened this year on July 5). The most extreme case of this is the week between the Christmas holiday and New Year's Day, where the offices are practically empty. On these days of low demand, many services are scaled back and some choose to close entirely so that they can do inventory, perform routine maintenance, or upgrade equipment.

    One of the most visible service reductions is in food service. Smaller locations (such as snack bars) are closed, and the kitchens which remain open offer a reduced menu. But just because most people are on vacation doesn't mean that nobody is watching. Here's a menu from one kitchen that was posted almost exactly one year ago:

    Breakfast Roberts Waffles
    Breakfast Burrito
    Warm Tortilla filled with Scrambled Egg, Golden Hash Browns, Onion Green Chiles, Monterey Jack Cheese and Salsa.
    Today's Soups Clam Chowder
    Tomato Basil Bisque
    Exhibition Station Closed for Holiday
    Shanghai Shanghai
    Greek Potato Salad
    A delicious blend of potatoes, tomatoes, red onions, flavored with mustard, parsley, dill seed, mint and lemon juice.
    Wild Greens Grill and Greens
    Chef's Table Station Closed for Holiday
    Pizza Specialty Pizza by the Slice
    Deli Mozzarella, Tomato and Basil Panini
    Mozzarella, Tomato and Basil Panini
    Spcied [sic] Cranberry Turkey Salad Served on a Flaky Crossaint [sic]
    Entrée Check Freezer
    Grill Tuna Melt
    Steak Frites

    << Previous Day 2013/12/26
    [Calendar]
    Next Day >>

The Old New Thing   About Sviesta Ciba