Thread: Error when trying to use '__try' function

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    199

    Smile Error when trying to use '__try' function

    Hi,

    As stated I'm trying to get this to work. This is a project that is being compiled to make a static library. I'm working within Code::Blocks not Visual Express. I had a look on line and found the following file might be needed:

    #include <excpt.h>

    I included it but to no avail. I have the following error message:

    |59|error: '__try' was not declared in this scope|

    Now as far as I understand it this function might be bound to Windows specifically somehow but I'm not sure. I'm trying to compile it into a plain static library so maybe already that is a mistake I'm not sure. Is there some #include I can use here to get it to run or is there something more complicated going on that is OS dependent? I'm mainly a game programmer not a software engineer so this is a bit beyond me I'd appreciate any help anyone could offer, thanks.

  2. #2

  3. #3
    Registered User
    Join Date
    Jan 2010
    Posts
    199

    Smile Thanks

    That's an extremely useful reply indeed. Thanks for those links. It seems alot of extra 'manual' work has to be done here to get it to run on the GCC compilers.

    I tried this:
    Code:
    __try {
    
                          // function...... and a load of instructions
                         
                          }
    
       __except(EXCEPTION_EXECUTE_HANDLER) { // aborts execution in try block and jumps to this
          if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
             return info;         // cpu inactive
          return info;            // unexpected exception occurred
          }
        __end_except // this extra line is required by the libseh stuff
    Ok great so I added the required libseh stuff to the project and got no errors relating to files not found for it. Wasn't too bad to be honest just had to add a header to the project and include the __end_except line. Fine.

    But now my compiler is complaining about this:

    |85|error: expected 'catch' before '{' token|
    And alot of other errors. I'm fairly sure I know what those other errors are but I don't want to ask too much at the moment or I'll confuse the thread. For now it seems my compiler is recognising the __try function but it is not happy about seeing the __except part it seems to expect to see the catch keyword instead. Is there any way around this? All the guy who wrote this code seems to want to do is run a block of code, and run a special block of code afterwards if something failed.

    Can this be re-written in a more simple way or is there some way I can get my compiler to be happy about this __except keyword?

  4. #4
    Registered User
    Join Date
    Jan 2010
    Posts
    199
    Ok to make things simpler I wrote my own simple test:
    Code:
    #include <iostream>
    
    #include "seh.h"
    
    int main()
    {
        __try
        {
            int n = 1/0;
        }
    
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
    
            //if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION) // this is the previous version
            //from the original author but the function _exception_code was not found
    
            if (GetExceptionCode() == STATUS_ILLEGAL_INSTRUCTION)
            {
                std::cout << "Exception code if statement has run" << std::endl;
            }
    
            std::cout << "Exception code has run" << std::endl;
        }
    
        __end_except
    It almost compiles but then produces the following errors. Looks like some kind of dependency is missing:

    |7|undefined reference to `__seh_register@4'|
    |15|undefined reference to `GetExceptionCode'|
    |23|undefined reference to `__seh_unregister@0'|
    So I'm pretty close. The GetExceptionCode error must be some typical vanilla standard file I'm not linking to as I know it's a common function. The only bit that worries me are the seh references. I thought I'd already done everything required. There are some 'Makefiles' and the like in the libseh download which I don't recognise. I don't even know what a 'Makefile' is but I'm guessing I'm missing something by not using them and that's where the dependency issue is coming from.

    Am I on the right track? Any ideas?>

    Many thanks

  5. #5
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,130
    What's wrong with normal try/catch blocks? Why are you using __try?


    Code:
    try
    {
        // do something
    }
    catch(...)
    {
        std::cout << "it failed";
    }
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

  6. #6
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Because C++ exceptions != SEH exceptions. That only works in VC if you use some special compiler flags

  7. #7
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    I would think whether catching SEH exceptions is necessary. If your code can divide by zero, access invalid memory location, etc. it's definately not the solution! Make assertions where needed and find all the bugs which cause such errors. Use SEH with care and only when necessary (for example, when an external library may crash), otherwise your code will not be portable.

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Looks like some kind of dependency is missing
    You need to build and link with libseh.a.

    I ran into some issues doing this with "gcc version 4.5.1 (tdm-1)".

    I had to fix an error when I tried to build the library. Adding "#include <stdio.h>" to common\sehpp.cpp fixed that.

    However, there is a major problem with using this library with C++ code in my version of MinGW. The libStdC++ that comes with it (ver. 20100731) is already using the macro "__try" (in \lib\gcc\mingw32\4.5.1\include\c++\exception_defin es.h in my version).

    So if you want to use this library with C++, you may need to rename "__try" to something like "__seh_try" in \libseh-0.0.3\os\windows\seh-support.h

    To build the library: open a cmd prompt - run mingwvars.bat in the root of your MinGW install - cd into libseh-0.0.3\ - run "mingw32-make -f Makefile.mingw32". This will create a version of the library with debug output. For a build with no debug output, edit the makefile and remove "-DDEBUG".

    gg

  9. #9
    Registered User
    Join Date
    Jan 2010
    Posts
    199
    That's great thanks for all those replys, especially yours CodePlug. The original code author wanted to make sure he could make a check for an error of type:

    STATUS_ILLEGAL_INSTRUCTION

    So I don't want to deviate from that much. The whole code is there to arrange some assembler language instructions and acquire information about the CPU. I wonder if a simple try catch thing were done would it have this functionality in it? Anyways, I'm going to try and get this to work now by making that static library and linking. Thanks so much I'll report back how it goes

  10. #10
    Registered User
    Join Date
    Jan 2010
    Posts
    199
    Ok I had another go and hit the exact problem you described. The __try function does indeed overwrite an existing definition causing weird compiler behaviour. Even the error messages don't make it obvious what's going on, it just complains it can't find the 'catch' keyword at the end of the '__try' block.

    I even attempted the '__try1' version which my compiler found in it's little drop down menu but then complained when compiling that '__try1' was not declared in this scope. I have positively no idea why it would do this.

    Anyway this is getting drawn out and I really just want to progress as all I'm trying to do is compile a static library my game engine uses for fast math stuff using assmebler language.

    Provided an error in the 'try' block can be caught as a STATUS_ILLEGAL_INSTRUCTION by the function that gets the error code I don't really need to know anything more. Sure I could go into the libseh stuff and change the function name, but for sure that would then cause a knock-on problem somewhere else within the libseh stuff which would mean yet more work to fix/update.

    So my question is which of the following 2 options are best? :

    1) Substitute the original code with a simple try/catch block. This would mean I'd have to acquire an error code of type STATUS_ILLEGAL_INSTRUCTION to make sure the code ran totally true to the original author's intentions.

    2) If the simple try/catch method cannot perform the job requested then I suppose I'd have to delve into all that libseh stuff and write individual function names. I really don't want to do this because then I wonder what knock-on effects there would be for things like the makefile and all that stuff. Sure it would teach me something but I'd rather avoid it if I can!

    So what should I do? Many thanks for any help offered

  11. #11
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Sure I could go into the libseh stuff and change the function name ...
    The only thing you have to change is a macro name - and add a #include to make the library build.

    1) \libseh-0.0.3\libseh-0.0.3\common\sehpp.cpp
    Add "#include <stdio.h>" on line 37

    2) \libseh-0.0.3\libseh-0.0.3\os\windows\seh-support.h
    Line 201, rename "__try" to "__seh_try"
    Line 228, rename "__try" to "__seh_try"

    That's it. Using a different macro name prevents name collisions with libStdC++.

    Code:
    #include <iostream>
    #include "seh.h"
    
    int main()
    {
        __seh_try
        {
            volatile int n = 1/0;
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            if (GetExceptionCode() == STATUS_ILLEGAL_INSTRUCTION)
                std::cout << "Exception code if statement has run" << std::endl;
            std::cout << "Exception code has run" << std::endl;
        }
        __end_except
        
        return 0;
    }
    Works as expected.

    gg

  12. #12
    Registered User
    Join Date
    Jan 2010
    Posts
    199
    Wow sounds great I'll check it out and report back Thanks so much!

  13. #13
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Code:
    #ifdef __GNUC__
    #   define SEH_TRY __seh_try
    #else
    #   define SEH_TRY __try
    #endif
    
    #define SEH_EXCEPT __except
    #define SEH_ENDEXCEPT __end_except
    Looks much better IMO.

  14. #14
    Registered User
    Join Date
    Jan 2010
    Posts
    199
    Thanks kmdv

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Installing a handler for illegal instructions is really weird. Why would there be an illegal instruction, and how would the software recover from it if so? Is there some kind of dynamic code generation going on?

    Is this code doing... ahem... "funny stuff?"
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling C in Visual Studio 2005
    By emanresu in forum C Programming
    Replies: 3
    Last Post: 11-16-2009, 04:25 AM
  2. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  3. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM