SFML community forums

Help => System => Topic started by: Acumen on August 12, 2015, 05:43:36 am

Title: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 12, 2015, 05:43:36 am
So first off, I am in an old 2.1X snapshot from November 2014, running on Windows 8. I am going to update to the latest snapshot ASAP, but seeing if this is something that is on the radar at all? Searching didn't turn anything up.

Story is 4 x 360 controllers, 2 x wireless 2x wired. Things run well unless controllers go to sleep or are disconnected. Then anywhere from 1 to 20 seconds after I will get a crash. I can see it is happening at pollEvent() from a debug log I setup.

Seems to be reliant on 4 controllers all being on prior to program start (as opposed to being plugged in or turned on once running). Then having some specific controllers disconnect? Unplugging all 4 reproduces it, less than 4 not always, but sometimes. I am also able to reproduce it on an SFML project where I do not mess with the joystick at all so am fairly certain the issue is not in my code.

Will update snapshot and get a minimal example.
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Laurent on August 12, 2015, 07:57:36 am
I don't see any reason to post a bug report before updating, especially with such an old version of SFML. Many bugs have been fixed, including joystick issues.

So... update first, please ;)
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 12, 2015, 05:33:04 pm
Yeah sorry. I was hoping maybe someone had an easy fix. Takes some time for me to relearn the whole process of building my version of SFML. Have some custom stuff in there (nothing with joysticks ;D).
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 13, 2015, 01:10:52 am
I updated to the latest 2.3.1X snapshot from Git, have minimal code, and can reproduce the problem.

int main(int argc, char *argv[])
{
        sf::Window testWindow;
        testWindow.create(sf::VideoMode::getDesktopMode(), "TEST", sf::Style::Resize);

        sf::Event event;
        int run = 1;

        while(run)
        {
                while(testWindow.pollEvent(event))
                {
                        if(event.type == sf::Event::Closed)
                        {
                                testWindow.close();
                                run = 0;
                        }
                }
                testWindow.display();
        }
        return 0;
}

Windows 8.1, happens with 4 controllers plugged in prior to start, then unplugged while running. Takes about 10 seconds for the crash to occur.

Does not seem to happen with less then 4 controllers in, or if controllers are plugged in after launch. Does sometimes occur if less then 4 controllers are unplugged, but seems dependent on the specific controller unplugged, which might change with reordering, and is not as reproducible as unplugging all 4.
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 13, 2015, 10:30:51 pm
OK! I made some headway. The problem is linked to JoystickImpl.cpp, line 192

cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;

Which is in the JoystickImpl::isConnected function below. When commenting it out, the program no longer crashes.

bool JoystickImpl::isConnected(unsigned int index)
{
    // We check the connection state of joysticks only every N milliseconds,
    // because of a strange (buggy?) behavior of joyGetPosEx when joysticks
    // are just plugged/unplugged -- it takes really long and kills the app performances

    ConnectionCache& cache = connectionCache[index];
    if (cache.timer.getElapsedTime() > connectionRefreshDelay)
    {
        cache.timer.restart();

        JOYINFOEX joyInfo;
        joyInfo.dwSize = sizeof(joyInfo);
        joyInfo.dwFlags = 0;

        cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
        return cache.connected;
    }
    else
    {
        return cache.connected;
    }
}

Interestingly, negating its effect by adding the line:

cache.connected = 0;

Immediately after, while leaving it in, still causes the crash. Seems it seems to be a problem in the Microsoft library itself?

Replacing:

cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;

With:

sf::err() << index;
sf::err().flush();
sf::err() << ":" << joyGetPosEx(JOYSTICKID1 + index, &joyInfo) << " ";
sf::err().flush();

Yielded final 2 lines:

0:167 1:167 2:167 3:167 4:165 5:165 6:165 7:165
0:167 1:167 2:167 3:167 4

So it seems to be crashing with the first controller that never existed after 4 have been disconnected? For my purposes I changed the Joystick::Count enum from 8 to 4, which fixes my crash, but obviously is not a real solution to the problem.
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Mario on August 14, 2015, 11:06:49 am
That sounds really weird. That API call should never crash, no matter what you pass. Do you happen to have any other (virtual) joysticks/gamepads installed? Unfortunately I've got only 3 XBox controllers (wireless 360, wired 360, and One).
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 14, 2015, 06:47:28 pm
I've used many different joysticks, bluetooth controllers, things like leap, Oculus, have a touchpad. Nothing else is plugged in right now though except the touchpad (laptop). I disabled every service/runtime I could find, including the touchpad, made sure all my anti-virus is off, still reproducible.

Unfortunately my other windows machines are out of commission right now.
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 17, 2015, 08:09:12 pm
Anyone able to try to reproduce out there? This could possibly be useful to someone else. It took me basically a year to figure out this issue. My SFML game doesn't even use 4 joysticks but sometimes when showing it after showing another 4 player game unity I am working on they would still be in and the crash would occur. I am however likely to forget about this topic if it goes to long without progress :)

What can I do to help?
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: binary1248 on August 17, 2015, 08:52:27 pm
What does calling joyGetNumDevs() return?
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: daire on August 18, 2015, 11:27:39 am
thank you
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 18, 2015, 05:53:21 pm
joyGetNumDevs() returns 16, doesn't change.
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: binary1248 on August 19, 2015, 04:30:10 pm
Maybe you can get a deeper callstack? One that goes into the Windows API and gives some clues about which module is causing the problem. Visual Studio provides symbols for some system modules.
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 20, 2015, 02:17:30 am
OK, so I don't normally do much in the way of stack tracing and dump stuff (although I always am interested to learn), so I may be doing something very wrong, but here is what I get and my process.

1. Program crash:

Problem Event Name:     APPCRASH
  Application Name:     Test.exe
  Application Version:  0.0.0.0
  Application Timestamp:        55d5185f
  Fault Module Name:    ntdll.dll
  Fault Module Version: 6.3.9600.17736
  Fault Module Timestamp:       550f42c2
  Exception Code:       c0000005
  Exception Offset:     00043701
  OS Version:   6.3.9600.2.0.0.768.101
  Locale ID:    1033
  Additional Information 1:     5861
  Additional Information 2:     5861822e1919d7c014bbb064c64908b2
  Additional Information 3:     a10f
  Additional Information 4:     a10ff7d2bb2516fdc753f9c34fc3b069

 2. Click debug, send to VS2013:

Unhandled exception at 0x77163701 (ntdll.dll) in Test.exe: 0xC0000005: Access violation reading location 0x00000000.

3. Click Break, Debug -> Window -> Call Stack

        ntdll.dll!RtlpLowFragHeapAllocFromContext()     Unknown
        ntdll.dll!RtlAllocateHeap()     Unknown
        KernelBase.dll!_LocalAlloc@8() Unknown
        dinput.dll!_ReallocCbPpv@8()   Unknown
        dinput.dll!_DIHid_GetDeviceInstanceId@12()     Unknown
        dinput.dll!_DIHid_GetDevInfo@12()      Unknown
        dinput.dll!_DIHid_BuildHidListEntry@8()        Unknown
        dinput.dll!_DIHid_BuildHidList@4()     Unknown
        dinput.dll!_hResIdJoypInstanceGUID_WDM@8()     Unknown
        dinput.dll!_JoyReg_GetConfig@16()      Unknown
        dinput.dll!_CJoyCfg_GetConfig@16()     Unknown
        winmmbase.dll!_joyOpen@8()     Unknown
        winmmbase.dll!_joyGetPosEx@8() Unknown
        Test.exe!sf::priv::JoystickImpl::isConnected(unsigned int)      C++
        Test.exe!sf::priv::JoystickManager::update(void)        C++
        Test.exe!sf::priv::WindowImpl::processJoystickEvents(void)      C++
        Test.exe!sf::priv::WindowImpl::popEvent(class sf::Event &,bool) C++
        Test.exe!sf::Window::pollEvent(class sf::Event &)       C++
>       Test.exe!main(int argc, char * * argv) Line 62  C++
 

So corrupted heap? From hardware/driver issue on my machine? Anyone out there with 4 controllers?
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 20, 2015, 03:22:50 am
So admittedly I have no idea what I am doing with this, but I tried setting gflags to monitor the heap and attached the exe to windbg, I get this output:

Critical error detected c0000374
(48a0.7ae4): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=c0000374 edx=00000021 esi=00000002 edi=0498ba60
eip=772055e7 esp=001dc120 ebp=001dc1b0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
ntdll!RtlReportCriticalFailure+0x46:
772055e7 cc              int     3
 
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: dabbertorres on August 20, 2015, 03:36:12 am
This thread (http://en.sfml-dev.org/forums/index.php?topic=13318.0) looks possibly related? Both are going through the same function call at least.

Though, I found this tweet (https://twitter.com/hartlabs/status/631934662378590210) that describes what sounds like to me what is going here in Acumen's situation. Though he solved it with a workaround ("Reducing controller count check to 4 solves it for me"), because according to him, it's a bug in Windows.

From what I did read on other stuff, most people claim WinMM (which I guess is what SFML is using in this case?) is "ancient", "deprecated", and in a "won't fix" state. Which is unfortunate.
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 20, 2015, 07:15:11 am
That's my tweet :)

Might have been a bit jumping the gun there claiming it's a Windows bug. I was excited I finally tracked down the cause of my intermittent crashes over the last year and a half, and well the stack leaded to Windows functions. Driver issue seems more likely now that I have calmed down ha.

Yeah I've seen all the discussions about it being deprecated. From what I have read there is very sound reason to stick with it though, lower level tried and true vs whims of Microsoft.

Interesting that they tracked it to watch software, driver conflicts I guess?
Title: Re: Joystick Disconnect causes Crash at pollEvent()
Post by: Acumen on August 20, 2015, 09:57:40 pm
So, good news...?

I finally got one of my other Windows 8.1 machines running. The problem is not reproducible on it, so it must be some hardware/driver issue. Ha from now on I have to keep this machine up as vital equipment. Makes me not want to add multi-platform support :). Need 2 of every kind like Noah or something.

Anyway downloading every driver update I can find. Not sure what else to try from here, maybe it works? I still find it odd my reducing the joystick count solves it so easily. Seems like it could pop up for other people. Think I will probably leave that fix in my build of SFML just because I don't really need it and would rather have to explain to people with 5 joysticks connected that they need to move them around to get the one they want to use to work than have any potential crashes.