Solved

exceptions processing question

Posted on 2004-10-24
379 Views
Last Modified: 2010-04-01
I'm using visual c++ 6.0 and have the following code:

int main(int argc, char **argv)
{

      try
      {
            const char *p=0;
            int i = strlen(p); // this throws exception
      }
      catch(exception exc)
      {
            cout << exc.what() << endl;
      }
      return 0;
}

Why when I put a break point inside catch, it never gets there. Vc++ just pops up unhandled exception at address dialog box.
I just want to process any exception here at main and write it to a log.
0
Question by:healingtao
    16 Comments
     
    LVL 86

    Expert Comment

    by:jkr
    That is not a C++ exception, but a Win32 exception - try

    int main(int argc, char **argv)
    {

        __try
        {
             const char *p=0;
             int i = strlen(p); // this throws exception
        }
        __except(1)
        {
             cout << GetExceptionCode() << endl;
        }
        return 0;
    }
    0
     

    Author Comment

    by:healingtao
    what do I need to declare for GetExceptionCode()  because it doesn't compile.
    Also I would like to write the description o the exception to a log file, how can I do it?
    0
     

    Author Comment

    by:healingtao
    compiler also specifies error C2712 - Cannot use __try functions that require object unwinding. I'm also getting a warning C4509
    0
     
    LVL 3

    Expert Comment

    by:Indrawati
    Hi

    I tried your code on my VC++ 6.0, and I get the sdame behaviour. I suspect strlen does not throw an exception that is derived from std::exception, hence the unhandled exception (BTW, it's usually better to catch exceptions by reference: http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.7). If you add the catch-all catch clause after the catch(exception &e):

    catch(...)
    {
    }

    the exception was caught properly.
    0
     
    LVL 39

    Expert Comment

    by:itsmeandnobodyelse
    >> compiler also specifies error C2712 - Cannot use __try functions

    __try and __except cannot used withe C++ objects that have destructors. So, it shouldn't be used in a C++ prog.

    try -  catch(...) works but gives no exception code and/or reason. To get both std::exception and (at least) catch other exceptions also, you should have this:


         try
         {
              const char *p=0;
              int i = strlen(p); // this throws exception
         }
         catch(exception exc)
         {
              cout << exc.what() << endl;
         }
         catch(...)
         {
              cout << "unknown exception" << endl;
         }
         return 0;

    Regards, Alex

    0
     
    LVL 86

    Expert Comment

    by:jkr
    >>So, it shouldn't be used in a C++ prog

    *Cough*. No comment.

    >>C2712 - Cannot use __try in functions that require object unwinding

    That means that you cannot have an object in that SEH handler frame. The common way around that is to put the code to be monitored in a separate function, e.g.

    void test ()
    {
       __try
       {
            const char *p=0;
            int i = strlen(p); // this throws exception
       }
       __except(1)
       {
            cout << GetExceptionCode() << endl;
       }
    }

    int main(int argc, char **argv)
    {

        test();

       return 0;
    }

    Another alternative is to translate SEH exceptions to C++ exceptions using a translator function and '_set_se_translator()':

    Example

    /*  SETRANS.CPP
     */

    #include <stdio.h>
    #include <windows.h>
    #include <eh.h>

    void SEFunc();
    void trans_func( unsigned int, EXCEPTION_POINTERS* );

    class SE_Exception
    {
    private:
        unsigned int nSE;
    public:
        SE_Exception() {}
        SE_Exception( unsigned int n ) : nSE( n ) {}
        ~SE_Exception() {}
        unsigned int getSeNumber() { return nSE; }
    };
    void main( void )
    {
        try
        {
            _set_se_translator( trans_func );
            SEFunc();
        }
        catch( SE_Exception e )
        {
            printf( "Caught a __try exception with SE_Exception.\n" );
        }
    }
    void SEFunc()
    {
        __try
        {
            int x, y=0;
            x = 5 / y;
        }
        __finally
        {
            printf( "In finally\n" );
        }
    }
    void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
    {
        printf( "In trans_func.\n" );
        throw SE_Exception();
    }

    0
     
    LVL 39

    Expert Comment

    by:itsmeandnobodyelse
    >>>> Cough*. No comment.

    MSDN says,

    ---------------------------------------------------------------------------------------------------
    Note   Structured exception handling works with Win32 for both C and C++ source files. However, it is not specifically designed for C++. You can ensure that your code is more portable by using C++ exception handling. Also, C++ exception handling is more flexible, in that it can handle exceptions of any type. For C++ programs, it is recommended that you use the new C++ exception-handling mechanism (try, catch, and throw statements).
    ---------------------------------------------------------------------------------------------------

    Any more *coughs*?

    Regards, Alex



    0
     
    LVL 86

    Expert Comment

    by:jkr
    Yes. I cannot read that it 'should not' be used there. Therefore, your statement is not correct. Period.
    0
     
    LVL 39

    Expert Comment

    by:itsmeandnobodyelse
    jkr, sometimes i absolutely don't know how a man of your experience and your reputation could behave so childishly.



    0
     
    LVL 86

    Expert Comment

    by:jkr
    >>behave so childishly

    What?
    0
     
    LVL 39

    Expert Comment

    by:itsmeandnobodyelse
    Ok, for peace i will explain. Though, i am sure you already know...

    >>>> __try and __except cannot used with C++ objects that have destructors.
    >>>> So, it shouldn't be used in a C++ prog.

    The asker had problems using a code snippet you've posted above and got compiler error C2712. I found out from MSDN that __try and __except couldn't be used when having C++ objects in the same function and that Structured Exception Handling (SEH) was *not recommended* for C++ programs but C++ exception handling was. Therefore, i told the asker, he/she "shouldn't use" that functionality but C++ try - catch mechanism. That's my recommendation and i'll maintain it. And MSDN makes the same recommendation but was not using the same words. A behavior that controverts these facts is childish.

    Regards, Alex
    0
     
    LVL 86

    Expert Comment

    by:jkr
    >>Structured Exception Handling (SEH) was *not recommended* for C++ programs

    You seem to have a *lot* of fantasy. And, I don't like to get insulted. Therefore I see no need to explain to you that every Windows binary (C++ or not) uses SEH.
    0
     

    Author Comment

    by:healingtao
    Guys,

    Please calm down. My goodness - I didn't realize that such a simple question would cause such an uproar.
    I truly appreciate both your input but frankly I'm a bit confused now which way to go.
    I at the moment have a c++ utility program (it's not windows or mfc). All I wanted to do was to capture any exception and to report it. Originally I prefered to use C++ exception-handling mechanism (try, catch, and throw statements) but I need the details of the exception. The problem is since I'm forced to use
        catch(...)
         {
              cout << "unknown exception" << endl;
         }
    I don't get any info about the exception, so for me it's useless. I need to use catch(exception exc) but this never gets called.

    So it seems I need to use SEH. I guess I need to use GetExceptionCode method. It has many return values and I would prefer to report description of the caught exception. How would you recommend I do it in an elegant manner, or is there a way to use catch(exception exc) mechanism?

    Thanks
    0
     
    LVL 39

    Assisted Solution

    by:itsmeandnobodyelse
    >>>> So it seems I need to use SEH

    Yes, if you need to call C runtime functions or other non-standard library functions and could not check the input parameters before calling - the strlen sample isn't an appropriate sample for that as the argument easily could be checked before - you need SEH as catch(...) wouldn't reveal the reason for the exception. However, my guess is that 90 percent of all non-C++ exceptions will be caused by invalid pointer arguments where it is easier to wrap these calls by using an own C++ exception rather than using SEH.

        int mystrlen(const char* psz)
        {
              if (psz == NULL)
                    throw MyNullPointerException("strlen");
              return strlen(psz);
        }

    or
        int mystrlen(const char* psz)
        {
              try
              {
                 return strlen(psz);
              }
              catch(...)
              {
                   if (psz == NULL)
                        throw MyNullPointerException("strlen");
                   else
                        throw MyInvalidStringPointerException("strlen");
              }
              return 0;
         }

    Of course, jkr's translation method is an alternative, if you unterstand it and if there is a practical way to use it for non-trivial function calls as well - e. g. for a call to a foreign library function that has C++ objects as arguments.

    Regards, Alex
    0
     
    LVL 86

    Accepted Solution

    by:
    Well, sorry to have caused some misunderstandings by not clearly stating what I really meant.

    1st of all, I support the MSDN statement to 'it is recommended that you use the new C++ exception-handling mechanism'. That is certianly true in terms that you should *not* *raise* SEH eceptions in your code, but cannot mean that 'Structured Exception Handling (SEH) was *not recommended* for C++ programs', since there are simply circumstances where you cannot do anything else but using SEH handlers - and that's when e.g.

         try
        {
             const char *p=0;
             int i = strlen(p); // this throws exception
        }
        catch(exception exc)
        {
             cout << exc.what() << endl;
        }
        catch(...)
        {
             cout << "unknown exception" << endl;
        }
        return 0;

    will not catch any SEH exceptions (not even 'catch(...)', which might see a 'Microsoft C++ exception' if translated by the CRT) since they're simply not thrown like C++ exceptions and use a completely different mechanism, which could be compared to UN*X signals. If you need to catch Windows specific exceptions, you are stuck with SEH, and that's why I am so opposed to the statement "it shouldn't be used in a C++ prog". That's a nice theory that should be supported, but in practise, you'll always end up having to, unless you write lab examples. And even an "Access Violation" does not comply with that...

    Of course I stand corrected when any code is provided - using no translators - that can catch e.g. an EXCEPTION_BREAKPOINT. I'd even be happy about that.
    0
     
    LVL 86

    Expert Comment

    by:jkr
    Um - replace 'happy' with 'grateful' in the last sentence :o)
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    6 Surprising Benefits of Threat Intelligence

    All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

    In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
    What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
    The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
    The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

    846 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    7 Experts available now in Live!

    Get 1:1 Help Now