Debugging FlightGear - Note A


The first piece of 'puzzling' code is -
// Enable floating-point exceptions for Windows
#if defined( _MSC_VER ) && defined( DEBUG )
// Christian, we should document what this does
_control87( _EM_INEXACT, _MCW_EM );

This page shows my 'exploration' of this topic, but since it is NEVER compiled, I forget it for now ...

Why is this only done in the DEBUG configuration? And as the 'comment' asks, exactly what does it do? Thankfully, with Microsoft Visual Studio, you get the subscription MSDN help library, thus you can just place the cursor on te '_control87' word, and hit F1 ... and voila, almost instant contextual help ... Here is, in part, what the MSDN help says about this -

Run-Time Library Reference
_control87, _controlfp
Get and set the floating-point control word.
unsigned int _control87(unsigned int new,unsigned int mask);
unsigned int _controlfp(unsigned int new,unsigned int mask);
new - New control-word bit values.
mask - Mask for new control-word bits to set.
Return Value
The bits in the value returned indicate the floating-point control state. See FLOAT.H for a complete definition of the bits returned by _control87.

Further down, in the 'Remarks:' the particular values used are shown as -
_MCW_EM (Interrupt exception mask) 0x0008001F
_EM_INEXACT 0x00000001

I decide to drop in some code, to see what the original value is, and what it is changed to - so I add -
printf( "Original: 0x%.4x\n", _control87( 0, 0 ) );
_control87( _EM_INEXACT, _MCW_EM );
printf( "New: 0x%.4x\n", _control87( 0, 0 ) );
but when I put a debug trap on the first printf(), there is no 'trap'?

Ok, I read more CAREFULLY ... the #if means it will always be excluded from the compile ... 'DEBUG' is NEVER defined in the standard MSVC IDE ... the two items are debug is '_DEBUG', and release is 'NDEBUG' ... so I alter the code to -
#if defined( _MSC_VER ) && defined( _DEBUG ) ... I also note that MSVC7 does not 'complain' that a 'breakpoint' can not be 'set', like MSVC6 used too ... on the next run, the output is -
Original: 0x9001f
New: 0x10001

But now that I can see that this is NEVER compiled, or used by FlightGear, I suggest that the code be removed ... still not fully understanding what the original coder was trying to set, but only in the debug configuration ... by adding the definition of 'DEBUG' ... maybe some mysteries are better left unsolved ;=))


Also in bootstrap.cxx is the code -

#ifdef _MSC_VER
int main ( int argc, char **argv );
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
main( __argc, __argv ); }

Why is WinMain defined? This is not a 'windows' application, per se ... it is a CONSOLE application, that 'opens' a GL (glut) window ... not quite the same thing ... 'removing' this code does nothing ... FG still compiles, and links ... what can its purpose be?

Coincidently, it does show two 'external' variables, namely '__argc', and '__argv', which can be used instead of the single line command line, that is pointed to by the LPSTR lpCmdLine ... just an 'alternative' way to process the 'command line' in a 'windows' application ...

Hint: If you want to be able to drop in some code, compile and link FG in the shortest possible time, then you need to enable incremental linking - Project, FlightGear Properties, Linker, General tag, 'Enable Incremental Linking', change to 'Yes (/INCRMENTAL)' - ... and another 'powerful' feature, associated with this, is the 'edit and continue' - FlightGear Property Pages, C/C++ pseudo folder, General tag, set 'Debug Information Format' to 'Program Database for Edit & Continue (/ZI) - ... be warned, changing properties like this will cause a FULL RE-COMPILE of every module ... just time ... but later, you can drop in some code, or alter some code, and on 'trace', the module will be re-compiled, and inserted into the running application ... this does not always work, but makes testing, changing, trying again, fast and easy, when it does ... especially since FG takes quite some time to load, even on 'fast' systems ...