(mingw/winapi) growing exe size when linking to psapi

Started by
9 comments, last by fir 10 years, 1 month ago

Linking pasapi should not (that would be nonsensical, since it's a C API) and, on my machine, does not force MinGW to enable exceptions.

Though using exceptions in any form does, obviously. Are you positively sure that you do not have anything like throw or catch in your sources? This includes headers from any other libraries that you may be including (which maybe have some #ifdef that you accidentially triggered?).

While I obviously cannot tell you the exact reason of why and where and how exception handling got turned on without my divining crystal ball, I can only tell you what the symptoms are. One of the files you uploaded on pastebin does contain the names and strings of the standard exception handling code, and the other one does not.

If you have MSYS or GnuWin or something similar on your computer, you can run something like grep exception psapilinked.exe to see yourself (or "unexpected" or "handler"). Or just use a hex editor (I used WinMerge to compare them, but HxD would work fine, too).

Advertisement

Linking pasapi should not (that would be nonsensical, since it's a C API) and, on my machine, does not force MinGW to enable exceptions.

Though using exceptions in any form does, obviously. Are you positively sure that you do not have anything like throw or catch in your sources? This includes headers from any other libraries that you may be including (which maybe have some #ifdef that you accidentially triggered?).

While I obviously cannot tell you the exact reason of why and where and how exception handling got turned on without my divining crystal ball, I can only tell you what the symptoms are. One of the files you uploaded on pastebin does contain the names and strings of the standard exception handling code, and the other one does not.

If you have MSYS or GnuWin or something similar on your computer, you can run something like grep exception psapilinked.exe to see yourself (or "unexpected" or "handler"). Or just use a hex editor (I used WinMerge to compare them, but HxD would work fine, too).

No all headers im using are windows.h (with lean and mean and extra lean) and some c standard lib thats all - and psapi.h here - maybe this

causes the exceptions? nothing other, I carefully add teh options to strip symbols, no exceptions, no runtime - I am using pure c code

but compile it in c++ mode, this is simple and pure winapi app

got no idea what causes this exceptions.. do they have runtime cost

involved (I would like to strip them out)

Linking pasapi should not (that would be nonsensical, since it's a C API) and, on my machine, does not force MinGW to enable exceptions.

Though using exceptions in any form does, obviously. Are you positively sure that you do not have anything like throw or catch in your sources? This includes headers from any other libraries that you may be including (which maybe have some #ifdef that you accidentially triggered?).

While I obviously cannot tell you the exact reason of why and where and how exception handling got turned on without my divining crystal ball, I can only tell you what the symptoms are. One of the files you uploaded on pastebin does contain the names and strings of the standard exception handling code, and the other one does not.

If you have MSYS or GnuWin or something similar on your computer, you can run something like grep exception psapilinked.exe to see yourself (or "unexpected" or "handler"). Or just use a hex editor (I used WinMerge to compare them, but HxD would work fine, too).

I did some tests yet , my psapi code is like that



#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#include <windows.h>
 
#include <psapi.h>
 
#include "..\allmyheaders\allmyheaders.h"
 

long working_set_size = -1;
long paged_pool_size = -1;
long nonpaged_pool_size = -1;
 
static PROCESS_MEMORY_COUNTERS process_memory_counters;
 
long GetMemoryInfo()
{
 
    static HANDLE hProcess;
 
    static int initialised = 0;
    if(!initialised)
    {
    // return -1;
     static DWORD processID = GetCurrentProcessId();
    // return -2;
     hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID );
 
     if (NULL == hProcess)  ERROR_EXIT("cant open process for get memory info");
 
     initialised = 1;
 
 
    }
 
 
    if(GetProcessMemoryInfo(hProcess, &process_memory_counters, sizeof(process_memory_counters)))
    {
      working_set_size    = process_memory_counters.WorkingSetSize;
      paged_pool_size     = process_memory_counters.QuotaPagedPoolUsage;
      nonpaged_pool_size  = process_memory_counters.QuotaNonPagedPoolUsage ;
    }
 
    if(0)
      CloseHandle( hProcess );
 
    return working_set_size;
}
it shows that when i uncomment return -2 here my app has 75k when i uncomment return -1 (disabling the execution of
static DWORD processID = GetCurrentProcessId();
the app has 25k - is it possible, can it be explained?
(same with dynamic linking regardless of static or dynamic it seems
that it all depends on this " static DWORD processID = GetCurrentProcessId();" line

These two are quite hefty antipatterns:

I am using pure c code but compile it in c++ mode, this is simple and pure winapi app
#include "..\allmyheaders\allmyheaders.h"

You should either write C or C++ and compile the language that you use, not something different. C++ is not "C with some additional stuff", it is a different language with similar, but different rules. There is nothing wrong with writing C code, but then you should also compile as C. If you compile C++, then you should write C++.

Including "allmyheaders.h" is something that generally works, but it makes compilation needlessly slow, and you maybe bring definitions into scope which you don't need (or which even interfere in a non-obvious manner). It will also cause some people to raise an eyebrow when they look at your code, and will cause others to yell at you.

One notable difference of whether you compile C or C++ is for example that C++ (at least C++11, but GCC since ca. version 4.6 also does that for C++03) mandates initialization of function-local static variables being thread-safe. I'm mentioning that since you use that feature (maybe without being aware).

You most probably should not worry about exceptions. Do they have a runtime cost? Well, it depends, generally everything has a runtime cost. A better question would be whether they have a cost that matters, or a cost that is not justified by the benefits.

Giving a meaningful answer about exceptions is also hard since it depends a lot on what compiler build you use. MinGW can use setjump/longjump, DW2, and SEH exceptions. Which ones you have is determined when the compiler is built (on a proper build, you can figure out by running gcc -v).

SJLJ exceptions do have a runtime overhead, but even these are very acceptable, and the usefulness of exceptions still outweights their runtime cost in my opinion. DW2 exceptions make your exectuable somewhat bigger, but do not have a runtime overhead unless or until you actually throw (when trowing, they're indeed slightly slower). SEH exceptions combine the best of two worlds, but are presently only implemented in 64-bit builds (patent issues).

Exceptions have traditionally been accused of killing performance, but at least on a desktop, that is definitively not the case (it might be on a console). Like most language features, exceptions can be used for good and for evil. If you use them in a reasonable manner, their overhead will be very low (close to zero), but they will be immensely useful and greatly improve your code quality.

If you abuse them, ... well, the opposite. smile.png

disabling GetCurrentProcessId() [...] can it be explained?

I can't explain that. Does not seem like this is possible.

These two are quite hefty antipatterns:

I am using pure c code but compile it in c++ mode, this is simple and pure winapi app
#include "..\allmyheaders\allmyheaders.h"

You should either write C or C++ and compile the language that you use, not something different. C++ is not "C with some additional stuff", it is a different language with similar, but different rules. There is nothing wrong with writing C code, but then you should also compile as C. If you compile C++, then you should write C++.

Including "allmyheaders.h" is something that generally works, but it makes compilation needlessly slow, and you maybe bring definitions into scope which you don't need (or which even interfere in a non-obvious manner). It will also cause some people to raise an eyebrow when they look at your code, and will cause others to yell at you.

One notable difference of whether you compile C or C++ is for example that C++ (at least C++11, but GCC since ca. version 4.6 also does that for C++03) mandates initialization of function-local static variables being thread-safe. I'm mentioning that since you use that feature (maybe without being aware).

You most probably should not worry about exceptions. Do they have a runtime cost? Well, it depends, generally everything has a runtime cost. A better question would be whether they have a cost that matters, or a cost that is not justified by the benefits.

Giving a meaningful answer about exceptions is also hard since it depends a lot on what compiler build you use. MinGW can use setjump/longjump, DW2, and SEH exceptions. Which ones you have is determined when the compiler is built (on a proper build, you can figure out by running gcc -v).

SJLJ exceptions do have a runtime overhead, but even these are very acceptable, and the usefulness of exceptions still outweights their runtime cost in my opinion. DW2 exceptions make your exectuable somewhat bigger, but do not have a runtime overhead unless or until you actually throw (when trowing, they're indeed slightly slower). SEH exceptions combine the best of two worlds, but are presently only implemented in 64-bit builds (patent issues).

Exceptions have traditionally been accused of killing performance, but at least on a desktop, that is definitively not the case (it might be on a console). Like most language features, exceptions can be used for good and for evil. If you use them in a reasonable manner, their overhead will be very low (close to zero), but they will be immensely useful and greatly improve your code quality.

If you abuse them, ... well, the opposite. smile.png

disabling GetCurrentProcessId() [...] can it be explained?

I can't explain that. Does not seem like this is possible.

this allmyheaders.h is only with my own headers, from different modules (added here for convenience, (not to inllude specyfic list each one for each include) some way of short, also this 'my' name suggest this is some playfield (this is experimantal home project and not large)- except mu ovn headers I am using onlu std c lib (like stdio.h math.h stdlib.h) and windows.h

well my tests showed what i said if i wil uncomment return it is 75 k

if i give return vefore thi it is 25k

as to c /c++

I am big fan of c and not use c++ features, but i cant stand one thing

const int tab_max = 1000; //at global/file scope

int tab[tab_max];

it wil not compile in c - so i just need to switch to c++ simply for this

one 'feature' (the only one i use)

One notable difference of whether you compile C or C++ is for example that C++ (at least C++11, but GCC since ca. version 4.6 also does that for C++03) mandates initialization of function-local static variables being thread-safe. I'm mentioning that since you use that feature (maybe without being aware).

BINGO, (what a shit is this ;c )

I just turned


static DWORD processID =  GetCurrentProcessId();

into


static DWORD processID = 0;
 processID = GetCurrentProcessId();
and the size dropped down from 75k to 27k
also spped of the ap from 4ms/frame dropped to 3ms/frame
so it seem there was some overgead or something
scary, important lesson learned - avoid such kind of static 'initialisations' (scarry , realy scary, i very much dislike when compiler do thi kind of staf degrading performance)

This topic is closed to new replies.

Advertisement