We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2185 - Exception is thrown when attempting to debug an opengl application through gDebugger
Summary: Exception is thrown when attempting to debug an opengl application through gD...
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: thread (show other bugs)
Version: 2.0.0
Hardware: x86_64 Windows (All)
: P2 minor
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-26 13:38 UTC by kevin
Modified: 2019-05-25 08:47 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description kevin 2013-10-26 13:38:45 UTC
When debugging an OpenGL application through gDebugger : [http://www.gremedy.com/download.php]

An exception is thrown when the application attempts to start up.

The Exception is thrown from the file : 
src/thread/windows/sdl_systhread.c

at line number : 191 
[RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf);]

Function in question : 
SDL_SYS_SetupThread(const char *name)
{
    if (name != NULL) {
        #if (defined(_MSC_VER) && defined(_M_IX86))
        /* This magic tells the debugger to name a thread if it's listening.
            The inline asm sets up SEH (__try/__except) without C runtime
            support. See Microsoft Systems Journal, January 1997:
            http://www.microsoft.com/msj/0197/exception/exception.aspx */
        INT_PTR handler = (INT_PTR) ignore_exception;
        THREADNAME_INFO inf;

        inf.dwType = 0x1000;
        inf.szName = name;
        inf.dwThreadID = (DWORD) -1;
        inf.dwFlags = 0;

        __asm {   /* set up SEH */
            push handler
            push fs:[0]
            mov fs:[0],esp
        }

        /* The program itself should ignore this bogus exception. */
        RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf);

        __asm {  /* tear down SEH. */
            mov eax,[esp]
            mov fs:[0], eax
            add esp, 8
        }
        #endif
    }
}
Comment 1 Sam Lantinga 2013-11-03 18:58:31 UTC
This is fixed in 2.0.1
Comment 2 Vitaly Novichkov 2016-04-28 09:21:10 UTC
GDB in MinGW 4.9.2 stops with "Unknown signal" "Got exception 0x406D1388" because same thing.

[line 175] in src/thread/windows/SDL_systhread.c
RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR*) &inf);

I used most recent (6ad89111cb4f) tarball from here (https://hg.libsdl.org/SDL/) which I built SDL2 myself. (./configure --prefix=..; make; make install)

Error happens on attempt to do SDL_Init() (In two apps of my project I doing Audio-only in editor or Everything in game engine)
Comment 3 Vitaly Novichkov 2016-04-28 09:22:46 UTC
P.S. Same OS Windows 7, same architecture x86_64.
On Linux and on OS X I have no troubles with debuggers.
Comment 4 Vitaly Novichkov 2016-04-28 11:00:48 UTC
P.P.S. Temporary to escape this trouble, I completely commented code in the SDL_SYS_SetupThread(const char *name) function, but at evening I'll try to look for fix myself if you will not fix that before me
Comment 5 yrizoud 2016-07-09 18:27:56 UTC
Can confirm the same behavior with today's sources (2.0.4.10157), when trying to use gdb.
Please get rid of "RaiseException( 0x406D1388, ..)" : By design, this feature halts the program if any non-Microsoft debugger tries to run it. I don't see any good in it.
Comment 6 Vitaly Novichkov 2017-05-19 19:48:09 UTC
(In reply to yrizoud from comment #5)
> Can confirm the same behavior with today's sources (2.0.4.10157), when
> trying to use gdb.
> Please get rid of "RaiseException( 0x406D1388, ..)" : By design, this
> feature halts the program if any non-Microsoft debugger tries to run it. I
> don't see any good in it.

Or just put it under #ifdef _MSC_VER macros
Comment 7 Ryan C. Gordon 2017-05-19 21:04:03 UTC
(In reply to Vitaly Novichkov from comment #6)
> (In reply to yrizoud from comment #5)
> > Can confirm the same behavior with today's sources (2.0.4.10157), when
> > trying to use gdb.
> > Please get rid of "RaiseException( 0x406D1388, ..)" : By design, this
> > feature halts the program if any non-Microsoft debugger tries to run it. I
> > don't see any good in it.
> 
> Or just put it under #ifdef _MSC_VER macros

Builds of SDL can be used with Visual Studio if built with something else (as is the case with our official builds), and builds made with something else can be used in an app that is being debugged under Visual Studio.

(or debugged by something that isn't a traditional debugger, like gDebugger, in any case).


This is the current state of this issue:

- We thought we "fixed" it when Sam commented before. We've thought we fixed it like six or seven times now.  :)

- Since we can't actually fix it (we have to call RaiseException, we can't prevent debuggers from catching exceptions, etc) the latest in revision control sets you set a hint or environment variable at runtime to prevent the RaiseException call:

SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1");

(or export the environment variable SDL_WINDOWS_DISABLE_THREAD_NAMING=1)

If you never intend to use Visual Studio on your app, you can just stick this call in main() and be done with it, or set it just when you use gDebugger, etc.

- As of the Windows 10 Creators Edition, there's an official win32 API for naming threads that doesn't need RaiseException, and we use it, but you need the latest OS release for it to be available and most tools don't support it (and older tools, like Visual Studio 2015 and earlier, never will), but eventually, this will be the preferred way to do things and we'll remove the RaiseException code entirely.

- Things like gDebugger should really just implement a check for this magic exception, but that's beyond my control.


Anyhow, you now have the power to work around the problem, so that's the best we can do until the new API gets more popular.

--ryan.
Comment 8 Vitaly Novichkov 2017-05-19 21:13:51 UTC
(In reply to Ryan C. Gordon from comment #7)
> (In reply to Vitaly Novichkov from comment #6)
> > (In reply to yrizoud from comment #5)
> > > Can confirm the same behavior with today's sources (2.0.4.10157), when
> > > trying to use gdb.
> > > Please get rid of "RaiseException( 0x406D1388, ..)" : By design, this
> > > feature halts the program if any non-Microsoft debugger tries to run it. I
> > > don't see any good in it.
> > 
> > Or just put it under #ifdef _MSC_VER macros
> 
> Builds of SDL can be used with Visual Studio if built with something else
> (as is the case with our official builds), and builds made with something
> else can be used in an app that is being debugged under Visual Studio.
> 
> (or debugged by something that isn't a traditional debugger, like gDebugger,
> in any case).
> 
> 
> This is the current state of this issue:
> 
> - We thought we "fixed" it when Sam commented before. We've thought we fixed
> it like six or seven times now.  :)
> 
> - Since we can't actually fix it (we have to call RaiseException, we can't
> prevent debuggers from catching exceptions, etc) the latest in revision
> control sets you set a hint or environment variable at runtime to prevent
> the RaiseException call:
> 
> SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1");
> 
> (or export the environment variable SDL_WINDOWS_DISABLE_THREAD_NAMING=1)
> 
> If you never intend to use Visual Studio on your app, you can just stick
> this call in main() and be done with it, or set it just when you use
> gDebugger, etc.
> 
> - As of the Windows 10 Creators Edition, there's an official win32 API for
> naming threads that doesn't need RaiseException, and we use it, but you need
> the latest OS release for it to be available and most tools don't support it
> (and older tools, like Visual Studio 2015 and earlier, never will), but
> eventually, this will be the preferred way to do things and we'll remove the
> RaiseException code entirely.
> 
> - Things like gDebugger should really just implement a check for this magic
> exception, but that's beyond my control.
> 
> 
> Anyhow, you now have the power to work around the problem, so that's the
> best we can do until the new API gets more popular.
> 
> --ryan.

I think, is still be better to disable support for RaiseException for non-MSVC compilers by _MSC_VER macros. Not many people will guess that need to disable thread naming to escape this bug and will spend lot of time with this. Myself I prefer MinGW because GCC which a base of it, takes new C/C++ standards support much faster than MSVC, and most of my applications are incompatible with MSVC (the worst case is C++11 features in the templates support).
Comment 9 Ryan C. Gordon 2017-06-06 17:22:34 UTC
As a follow up, we ended up disabling the thread naming by default; the hint now defaults to disabling it, and Visual Studio users can enable it if they want.

--ryan.
Comment 10 Sam V 2019-05-25 08:47:00 UTC
This may be happening because the code to name threads by exception isn't correct. See this issue for why: https://developercommunity.visualstudio.com/content/problem/280049/native-code-setting-thread-name-causes-process-shu.html

You're supposed to wrap the RaiseException call in a try except handler:
__try{  
    RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);  
}  
__except (EXCEPTION_EXECUTE_HANDLER){  
}  

Without this the exception is just being thrown without anything to catch it if the debugger doesn't know about it.

I checked the commits for this code and the original code was very similar to this: https://github.com/SDL-mirror/SDL/commit/314ecabd38f35d84b4c60df5f1a642b5688ea9aa

Aside from using a different exception filter it's working as it should be there.

Later commits changed the try except to assembly code before being removed entirely in response to issue #2089.

My suggestion is to conditionally include the try except part as recommended by the MSDN docs if SDL is being compiled using the VC++ compiler. That should work for Windows targets compiled using the compiler that supports those keywords, while other compilers will work as they do now.

People who compile SDL using VC++ are likely to use the Visual Studio debugger as well so it should work properly, and the managed debugger won't take issue with it if the response given by the MS rep is to be believed.

Also, see https://stackoverflow.com/questions/7244645/porting-vcs-try-except-exception-stack-overflow-to-mingw

MinGW apparently doesn't understand structured exceptions so trying to use this code when SDL has been compiled with that could just crash the entire program anyway. That should probably be tested so this code doesn't cause problems during debugging.