Crash when using __declspec(selectany)

Started by Marco, April 09, 2025, 04:51:48 PM

Previous topic - Next topic

Marco

Hi Pelle,

When compiled with version 13 (no errors or warnings), two of my GUI applications crash on execution.

After several tests, I found that the problem lies in the 'dwmapi.h' header file. Other of my GUI applications that don't use this header file compile and run just fine.

It seems that the crashes are due to the following three declarations:
EXTERN_C __declspec(selectany) const UINT c_DwmMaxQueuedBuffers = 8;
EXTERN_C __declspec(selectany) const UINT c_DwmMaxMonitors = 16;
EXTERN_C __declspec(selectany) const UINT c_DwmMaxAdapters = 16;

If I comment out the above three declarations, or replace them with:
static const UINT c_DwmMaxQueuedBuffers = 8;
static const UINT c_DwmMaxMonitors = 16;
static const UINT c_DwmMaxAdapters = 16;
the applications no longer crash.

'#pragma optimize(none), #pragma optimize(size), or #pragma optimize(time)' give the same result (crash on execution).

For testing, I added the three 'EXTERN_C __declspec(selectany) xxx' declarations to the 'dwmapi.h' header file of version 12.
When compiled with version 12 (and using the modified 'dwmapi.h' header file), both applications crash on execution.
When compiled with version 12 (and using the original 'dwmapi.h' header file), both applications run fine.

I then did another test. I included the '<sspi.h>' header file (just because it contains several 'EXTERN_C __declspec(selectany) xxx' declarations) in one of the two applications:
#define SECURITY_WIN32
#define _SEC_WINNT_AUTH_TYPES
#include <sspi.h>

When compiled with version 13 (no errors or warnings), the application crashes on execution.
If I comment out all the 'EXTERN_C __declspec(selectany) xxx' declarations in the '<sspi.h>' header file, the application compile and run just fine.

Marco

Pelle

Hello Marco,

There is no documentation about the constants c_DwmMaxQueuedBuffers, c_DwmMaxMonitors, c_DwmMaxAdapters and I suspect they may be useful mostly/only when building Windows itself.

I can't reproduce this. Crash how? Assigning constants in read-only memory will never work, but apart from that I can't think of a way for these constants to affect anything.

If you still have a problem, I need a complete example demonstrating the problem.

/Pelle

Marco

Hi Pelle,

My applications do not use these 3 constants, in fact I simply commented them out and everything works perfectly. The above replacement constants were copied from the ReactOS 'dwmapi.h' header file.

Quote from: Pelle on April 10, 2025, 09:36:47 AMI can't reproduce this. Crash how?

Both applications crash when calling very simple graphics functions. The functions called are as follows:

void GradientFillSingle(HDC hdc, RECT *rc, COLORREF clrStart, COLORREF clrEnd)
{
    TRIVERTEX vert[2];                // <-- crash app 1
    GRADIENT_RECT gRect = {0, 1};

    vert[0].x     = rc->left;
    vert[0].y     = rc->top;
    vert[0].Red   = ByteToColor16(GetRValue(clrStart));
    vert[0].Green = ByteToColor16(GetGValue(clrStart));
    vert[0].Blue  = ByteToColor16(GetBValue(clrStart));
    vert[0].Alpha = 0x0000;

    vert[1].x     = rc->right;
    vert[1].y     = rc->bottom;
    vert[1].Red   = ByteToColor16(GetRValue(clrEnd));
    vert[1].Green = ByteToColor16(GetGValue(clrEnd));
    vert[1].Blue  = ByteToColor16(GetBValue(clrEnd));
    vert[1].Alpha = 0x0000;

    GradientFill(hdc, vert, 2, &gRect, 1, GRADIENT_FILL_RECT_V);
}

inline void FilledRect(HDC hdc, COLORREF clr, RECT *rc)
{
    COLORREF clrPrev = SetBkColor(hdc, clr);   
    ExtTextOutW(hdc, rc->left, rc->top, ETO_OPAQUE, rc, L"", 0, NULL);
   
    SetBkColor(hdc, clrPrev);        // <-- crash app 2
}

As you said, I find it difficult to understand how these three constants affect other functions. Anyway, I'll see if I can reproduce the problem with a simpler project.

Side note: WinContig compiled with version 13 seems to perform some operations faster. Great.

Marco



Pelle

Still not a complete example. I can't guess what the problem is.
Also, far from obvious how this snippet relates to the reported problem...
/Pelle

Marco

Hello Pelle,

Quote from: Pelle on April 11, 2025, 05:08:09 PMStill not a complete example.

Yep, it certainly is not, and it was never meant to be. That is why I wrote afterwards "I'll see if I can reproduce the problem with a simpler project".

The two snippets are just.. oh, well, snippets in support of the sentence that was next ("I find it difficult to understand how these three constants affect other functions").

I probably wasn't clear about what I wanted to say.

Anyway, I was able to reproduce the problem with a simpler project. The project was downloaded from the following link:
https://www.smorgasbordet.com/pellesc/zip/ctlcolor.zip

You will find the test files as an attachment to this message.

I only added the following 5 instructions to the 'main.c' file (everything else has been left untouched):

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "comctl32.lib")

...

#include "myfile.h"
#include <dwmapi.h>

The 'myfile.h' header file contains only two declarations.

I don't use the IDE to compile my applications. I prefer to use batch files. So simply double-click the 'build.bat' file to compile the application. The batch file assumes that PellesC is installed in the default folder ('C:\Program Files\PellesC'). If not, please edit the batch file and change the value assigned to the 'PCPATH' environment variable, for example:

set PCPATH=c:\PellesC

When building, the compiler should give some warnings that can be ignored for the sake of this example.

The same switches I use to build my applications are used in the batch file.

When using the original 'dwmapi.h' header file, the application crashes on execution. If you comment out the 'EXTERN_C __declspec(selectany) xxx' declarations in the 'dwmapi.h' header file, the application no longer crashes. You will get the same behaviour with version 12 as well.

I hope this is of some help.

Marco

Robert

Quote from: Marco on April 10, 2025, 10:27:40 PMHi Pelle,

My applications do not use these 3 constants, in fact I simply commented them out and everything works perfectly. The above replacement constants were copied from the ReactOS 'dwmapi.h' header file.

Quote from: Pelle on April 10, 2025, 09:36:47 AMI can't reproduce this. Crash how?

Both applications crash when calling very simple graphics functions. The functions called are as follows:

void GradientFillSingle(HDC hdc, RECT *rc, COLORREF clrStart, COLORREF clrEnd)
{
    TRIVERTEX vert[2];                // <-- crash app 1
    GRADIENT_RECT gRect = {0, 1};

    vert[0].x     = rc->left;
    vert[0].y     = rc->top;
    vert[0].Red   = ByteToColor16(GetRValue(clrStart));
    vert[0].Green = ByteToColor16(GetGValue(clrStart));
    vert[0].Blue  = ByteToColor16(GetBValue(clrStart));
    vert[0].Alpha = 0x0000;

    vert[1].x     = rc->right;
    vert[1].y     = rc->bottom;
    vert[1].Red   = ByteToColor16(GetRValue(clrEnd));
    vert[1].Green = ByteToColor16(GetGValue(clrEnd));
    vert[1].Blue  = ByteToColor16(GetBValue(clrEnd));
    vert[1].Alpha = 0x0000;

    GradientFill(hdc, vert, 2, &gRect, 1, GRADIENT_FILL_RECT_V);
}

inline void FilledRect(HDC hdc, COLORREF clr, RECT *rc)
{
    COLORREF clrPrev = SetBkColor(hdc, clr);   
    ExtTextOutW(hdc, rc->left, rc->top, ETO_OPAQUE, rc, L"", 0, NULL);
   
    SetBkColor(hdc, clrPrev);        // <-- crash app 2
}

As you said, I find it difficult to understand how these three constants affect other functions. Anyway, I'll see if I can reproduce the problem with a simpler project.

Side note: WinContig compiled with version 13 seems to perform some operations faster. Great.

Marco




Hi Marco:

What functions in your app need dwmapi.h ?

Marco

Hello Robert,

At the moment I only use the 'DwmGetWindowAttribute' and 'DwmSetWindowAttribute' functions. More specifically, 'DwmSetWindowAttribute' is used to disable the animations on a specific window, while 'DwmGetWindowAttribute' is used to get the actual size of a window (i.e. to get the visible window bounds, not including the invisible resize borders). I could use run-time dynamic linking for just two functions, but I'm planning to use more functions in the future.

Marco

TimoVJL

Perhaps an optimization problem with -Ob1 ?
May the source be with you

Marco

Hello Pelle,

I did an additional test. If you replace:

#include <dwmapi.h>

with

#include <pdhmsg.h>

in the 'main.c' file, the application will still crash. If you comment out the following declaration:

EXTERN_C __declspec(selectany) const GUID S_PDH = {0x04d66358, 0xc4a1, 0x419b, {0x80, 0x23, 0x23, 0xb7, 0x39, 0x02, 0xde, 0x2c}};

in the 'pdhmsg.h' header file, the application no longer crashes.

Perhaps, as Timo suspected, it is a problem of optimising using '-Ob1'.

Marco