Bumping a old topic because I still have the described problem and I finally had some time for more investigation.
Note: opengl = the opengl sample of SMFL.
My test:
1. svn update to a certain revision
2. "Rebuild opengl" in "Release static" mode; this actually rebuilds sfml-system, sfml-window, sfml-graphics, sfml-main and said opengl sample
3. start opengl
4. see whether it crashes of not
All revisions I tried up to 651 do work. All revisions I tried from 652 upwards (652, 675, 700, 774, 900) crash. The log message of revision 652 is:
Removed sf::OpenGLCaps class
Removed exportation of GLEW functions
By using the function
_set_se_translator plus a selfwritten "translator" function (which translates from win32 hardware exceptions into std::exceptions) I found out a so called
EXCEPTION_ILLEGAL_INSTRUCTION occurs.
Intermission: to use the
_set_se_translator you need the following compiler settings:
Project Properties -> C/C++ -> Code Generation -> Enable C++ Exceptions = Yes With SEH Exceptions (/EHa)
More details about all that topic can be found
here.
By adding a lot more std::cerr and try/catch blocks I tried to locate the position of the problem. Unfortunately I was not able to find something "interesting" but still I am posting here in the hope that it helps other to keep searching. My "best" find is the info that something goes wrong in the constructor of
WindowImpl while initializing the joysticks. Some debug output gibberish:
create main window...
WindowSettings::WindowSettings
VideoMode::VideoMode with parameters
WindowSettings::WindowSettings
Window::Window with parameters
RenderWindow::RenderWindow with parameters [1]
VideoMode::VideoMode copy constructor
Window::Create [1]
Window::ForceContextInit
WindowImpl::New
- Win32 window
JoystickState::JoystickState (08865010)
JoystickState::JoystickState (08865040)
WindowImpl::WindowImpl
Joystick::UpdateState
- State...
JoystickState::JoystickState (0012CB2C)
- Caps...
- joyGetDevCaps...
- return...
JoystickState::operator= (08865010 = 0012CB2C)
JoystickState::~JoystickState (0012CB2C)
$ catched in WindowImpl::WindowImpl
JoystickState::~JoystickState (08865040)
JoystickState::~JoystickState (08865010)
$ catched in static WindowImpl::New
=== ERROR ===
std::exception occurred:
Create failed, reason:
ForceContextInit failed, reason:
sf::priv::WindowImpl::New failed, reason:
new WindowImplWin32 failed, reason:
myJoyStates[i] = myJoysticks[i].UpdateState() failed (i = 0), reason:
win32 exception occurred, reason:
illegal instruction
As you can see I added a constructor, copy constructor, destructor and assignment operator to
JoystickState, including some std::cerr output (the 8 digit numbers are memory address, simply outputing
*this).
For some wicked the reason the assignment operator in the constructor of
WindowImpl seems to fail:
myJoyStates[i] = myJoystick[i].UpdateState();
The
UpdateState(i) works but then the assignment fails - or something like that. Guesstimationtheory:
myJoyStates is not "there", meaning the assignment operator dumps data somewhere into memory where it assumes
myJoyStates to be but where it is not or is not anymore. Guesstimationtheoryreason: stack/heap corruption (partly based on what I describe below now).
Then I say "ooookay, who needs joysticks anyway, let's drop the whole crap!" and so I added the following:
WindowImpl::WindowImpl() :
myWidth (0),
myHeight (0),
myJoyThreshold(0.1f)
{
std::cerr << "WindowImpl::WindowImpl" << std::endl;
// ### TEST ###
std::cerr << " - INSTARETURN" << std::endl;
return;
...which results in the following debug output gibberish...
create main window...
WindowSettings::WindowSettings
VideoMode::VideoMode with parameters
WindowSettings::WindowSettings
Window::Window with parameters
RenderWindow::RenderWindow with parameters [1]
VideoMode::VideoMode copy constructor
Window::Create [1]
Window::ForceContextInit
WindowImpl::New
- Win32 window
JoystickState::JoystickState (08865010)
JoystickState::JoystickState (08865040)
WindowImpl::WindowImpl
- INSTARETURN
WindowImplWin32::WindowImplWin32
- Create a dummy window
- Create the rendering context
WindowSettings::WindowSettings
VideoMode::VideoMode with parameters
WindowImplWin32::CreateContext
- A
- B
- C
- C1
- C1a
$ catched in WindowImplWin32::WindowImplWin32
WindowImpl::~WindowImpl
JoystickState::~JoystickState (08865040)
JoystickState::~JoystickState (08865010)
$ catched in static WindowImpl::New
=== ERROR ===
std::exception occurred:
Create failed, reason:
ForceContextInit failed, reason:
sf::priv::WindowImpl::New failed, reason:
new WindowImplWin32 failed, reason:
CreateContext failed, reason:
win32 exception occurred, reason:
illegal instruction
The relevant code is in
src\SFML\Window\Win32\WindowImplWin32.cpp:
// Setup a pixel format descriptor from the rendering settings
PIXELFORMATDESCRIPTOR PixelDescriptor;
std::cerr << " - C1a" << std::endl;
ZeroMemory(&PixelDescriptor, sizeof(PIXELFORMATDESCRIPTOR));
std::cerr << " - C1b" << std::endl;
Oha. Zeromemorying a local variable does not work?!? Well, screw MS functions, us the good ol' memset:
memset(&PixelDescriptor, 0, sizeof(PIXELFORMATDESCRIPTOR));
Same result, bamm!
So while I have no clue whether the local variable
PixelDescriptor is in memory or not or wherever it might be, at least my compiler does consider it a problem to zeromemory it.
That combined with the "illegal instruction" wickedness makes me think "stack/heap" corruption because that is a decent cause to name when things go "really, really wrong beyond logical reasons".
Anyway, back to a bit more rational viewpoint: something on the way from ...
sf::RenderWindow App(sf::VideoMode(800, 600), "SFML OpenGL");
...in the
main function towards the initialization of joysticks within the construction of
WindowImpl (which happens during the construction of one of its derivative classes) "something" goes wrong. And probably leaves the stack/heap in a mess. Which causes a "illegal instruction" win32 exception. During the initialization of joysticks or during zeromemorying local variables.
Unfortunately this all only happens in Release mode, not in Debug mode. Probably because Debug mode a) always zeromemories all memory and variables and b) it allocates some "memory guards" around some memory pieces to detect memory corruption but which in my case does not detect it but actually hides it due to some important code parts being not overwritten due to the additional "memory guards" around something.
My best hope would be to be able to set a breakpoint even in Release mode and having a call stack with fully readable function names available at that breakpoint. I would need to know the relevant compiler settings for that. Without making any other changes so it doesn't get "Another Debug" mode where the problem does not happen anymore.
My next best hope would be that somebody reads all this thoughts and miraculously finds the missing puzzle piece. Actually it must be somewhere in revision 652 or is at least directly caused by the changes in revision 652 because that's the point where it starts to crash.
Over and out,
T.T.H.
*actuallyquitefrustrated*