Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: DInput update appears to cause an exception with Steam API  (Read 4825 times)

0 Members and 1 Guest are viewing this topic.

fallahn

  • Sr. Member
  • ****
  • Posts: 492
  • Buns.
    • View Profile
    • Trederia
DInput update appears to cause an exception with Steam API
« on: April 11, 2018, 07:16:00 pm »
When using the Steam API closing the application throws this error



(I later loaded the debug symbols for ntdll.dll to find the function is RtlFreeHeap())

 on any version of SFML since this commit 'Added support for interfacing with joysticks via DirectInput'. This happens on Windows 7/10 64bit using VS2017 and can be recreated thusly:


#include <SFML/Graphics.hpp>
#include <steam/steam_api.h>

int main()
{
    if(SteamAPI_Init())
    {
        sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
        sf::CircleShape shape(100.f);
        shape.setFillColor(sf::Color::Green);

        while (window.isOpen())
        {
            sf::Event event;
            while (window.pollEvent(event))
            {
                if (event.type == sf::Event::Closed)
                    window.close();
            }

            window.clear();
            window.draw(shape);
            window.display();
        }

        SteamAPI_Shutdown();
    }
    return 0;
}

 

Commenting out the two Steam specific lines stops the error from happening. I realise this is probably a Steam problem as much as anything and I shall be reposting this on the developer forums, but I'd like to point it out here as it is likely the next version of SFML (as the current revision all ready does) will break any games by people developing for Steam, who decide to update SFML.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10800
    • View Profile
    • development blog
    • Email
Re: DInput update appears to cause an exception with Steam API
« Reply #1 on: April 11, 2018, 08:56:32 pm »
Kind of odd, as both Myroid and Ironbell use the Steam API and have tested the RT optimization but haven't reported such an issue.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Ironbell

  • Jr. Member
  • **
  • Posts: 61
    • View Profile
    • Cendric
Re: DInput update appears to cause an exception with Steam API
« Reply #2 on: April 11, 2018, 10:14:57 pm »
Hey Fallahn, I just tested your code and it works fine for me, no crash, no nothing (also not when I'm playing Cendric). I got an XBox controller connected while trying it out, Steam running and the connection to Steam is set up.
Did you test with an x64 build? Debug or release version? Any other ideas what could be different?

fallahn

  • Sr. Member
  • ****
  • Posts: 492
  • Buns.
    • View Profile
    • Trederia
Re: DInput update appears to cause an exception with Steam API
« Reply #3 on: April 11, 2018, 10:33:33 pm »
I've tested this at work, Windows 10 pro 64 with no controller attached in both debug and release. I've also tried it at home with Windows 7 64 Home Edition with no controller, an X360 controller and an XBONE controller, again in debug and release. All builds have been 64 bit. The only thing I think might be different is the version of Windows SDK? Apparently I'm using 10.0.16299.0

myroidtc

  • Newbie
  • *
  • Posts: 38
    • View Profile
    • Myroid-Type Comics
    • Email
Re: DInput update appears to cause an exception with Steam API
« Reply #4 on: April 12, 2018, 03:43:39 am »
Using the latest SFML build, Windows 10, VS2015, controller attached and supported, Steam API with Zeran's Folly. No errors with either the game or the sample code. I'm not sure if it matters but you have the steam_appid.txt file available, right?

Also using SFML static-linked if that matters.
« Last Edit: April 12, 2018, 03:46:04 am by myroidtc »

fallahn

  • Sr. Member
  • ****
  • Posts: 492
  • Buns.
    • View Profile
    • Trederia
Re: DInput update appears to cause an exception with Steam API
« Reply #5 on: April 12, 2018, 11:03:30 am »
Yeah I have the appid all set correctly. This is actually my second Steam project, the first one (released today!) is working fine with an older revision of SFML - I just decided to update while I work on this new project. I ended up spending a couple of hours in the checkout->build->test cycle narrowing the problem down to this commit. That's the odd thing, if I move to one revision earlier everything works fine.

I guess there's something wrong with both of my dev environments in that case... but I have no idea what :/

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10800
    • View Profile
    • development blog
    • Email
Re: DInput update appears to cause an exception with Steam API
« Reply #6 on: April 12, 2018, 11:19:26 am »
What's your DirectX installation? Or DInput version?
« Last Edit: April 12, 2018, 11:37:53 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

fallahn

  • Sr. Member
  • ****
  • Posts: 492
  • Buns.
    • View Profile
    • Trederia
Re: DInput update appears to cause an exception with Steam API
« Reply #7 on: April 12, 2018, 01:57:06 pm »
DXDiag doesn't give me anything more helpful than 'DirectX12'. As I understand it DirectInput is frozen at 8 anyway, since microsoft favours XInput these days

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: DInput update appears to cause an exception with Steam API
« Reply #8 on: April 15, 2018, 03:42:43 am »
Try this:
#include <SFML/Graphics.hpp>
#include <steam/steam_api.h>
#include <cstdlib>
 
int main()
{
    if(SteamAPI_Init())
    {
        std::atexit([]{ SteamAPI_Shutdown(); });
        sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
        sf::CircleShape shape(100.f);
        shape.setFillColor(sf::Color::Green);
 
        while (window.isOpen())
        {
            sf::Event event;
            while (window.pollEvent(event))
            {
                if (event.type == sf::Event::Closed)
                    window.close();
            }
 
            window.clear();
            window.draw(shape);
            window.display();
        }
    }
    return 0;
}
 
I have this weird feeling that whatever is going on inside the Steam DLL doesn't like it when applications call through its hooks after it has been shut down.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

fallahn

  • Sr. Member
  • ****
  • Posts: 492
  • Buns.
    • View Profile
    • Trederia
Re: DInput update appears to cause an exception with Steam API
« Reply #9 on: April 16, 2018, 11:18:32 am »
Unfortunately it makes no difference. I found this in the API docs for SteamAPI_Shutdown():

Quote
This will not unhook the Steam Overlay from your game as there's no guarantee that your rendering API is done using it.

So it seems the client handles the unhooking itself somewhere else :(

EDIT
OK so after digging around the Steam developer forums it appears that Steam uses DirectInput itself for a wrapper which makes all controllers appear as XInput devices in big picture mode. If I call SteamAPI_Init() *after* creating a window the problem goes away. Presumably it detects DirectInput is already being used somewhere (I've not looked into DirectInput myself to see how the API works so I'm making a few assumptions here) and makes sure it's initialised correctly, preventing the apparent double delete exception. So for me personally this is a fix for my current project (hooray!) but is this something SFML might want to handle - ie should it check if DirectInput is already being used (if it can even do that?)
« Last Edit: April 16, 2018, 01:00:52 pm by fallahn »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: DInput update appears to cause an exception with Steam API
« Reply #10 on: April 16, 2018, 06:40:16 pm »
Checking if and who is using DirectInput is not something we can do across process boundaries. Probably by design and by chance.

The whole idea behind the COM and IUnknown interface that DirectInput also uses is that you grab a handle to the interface before using it. This increments an internal reference count. When ->Release() is called, the reference count is decremented and when it goes down to 0 it is destroyed. Nothing new here. If multiple people make use of it, then they don't have to know if or who is using it simultaneously. As long as everybody ->Acquire()s and ->Release()s the interface properly everything should work out. This is under the assumption that they willingly share the same object with each other somehow. The stack trace in your screenshot looks kind of like a double delete/free. This can only happen if someone isn't playing by the rules.

Because of how the overlay works (that thing that is rendered on top of your game that you can control with keyboard and mouse, obvious culprit judging from the stack trace), I am fairly certain that it tries to hook DirectInput. It basically "pretends" to us like it is the real DirectInput even though it isn't. In order to intercept and when applicable block input events from reaching our code, they need to do some funky stuff in theirs. This is the reason why they couldn't simply just create their own DirectInput object and had to hijack ours. The facts are kind of clear. We create an object (which implies ->AddRef()). And at some point we destroy the object with ->Release(). From our perspective, nothing else can happen in between. A double delete/free can only happen if they also play around with the the reference count for an object that we own.

There is nothing we can do. If they want/have to hook a DLL, then the least they can do is at least try to make sure it behaves like the real deal under all circumstances, yes... including C++ code... that doesn't make use of SDL... with static object destructors... that can ->Release() objects after main() returns. This tendency to design everything under the assumption that everybody programs in C style can be kind of disturbing at times...
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).