Solved

Try / Catch

Posted on 2007-03-29
8
407 Views
Last Modified: 2008-01-09
Hi,

It's been a while that i've not program in C++. I remember how to use try / catch but I want to catch only exception that are Errors not every exception.

I explain. Some time my program quit with the message "memory cannot be read". I know where but not when. So I what to put a try catch around it. But if I put Catch (...) it always pass in the catch and I don't what it.

Did someone know what Exception I need to catch?

Thank you...

(Sorry for my poor english, It's not my first language)
0
Comment
Question by:lussier
  • 5
  • 2
8 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 18817105
>>Some time my program quit with the message "memory cannot be read". I
>>know where but not when. So I what to put a try catch around it. But if I
>>put  Catch (...) it always pass in the catch

That is because access violations are no C++ exceptions, but Windows SEH exceptions, which is a different mechanism. These are caught using

__try {

int* p = NULL;

int n = *p;

} __except(1) {

// catch "memory cannot be read"
}

Alternatively, you can specify a translator funciotn which translates SEH exceptions into C++ exceptions, see e.g. http://msdn2.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx ("_set_se_translator ") which works like

// crt_settrans.cpp
// compile with: /EHa
#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; }
};
int 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 86

Expert Comment

by:jkr
ID: 18817121
See also http://msdn2.microsoft.com/en-us/library/de5awhsw.aspx ("Exception Handling Differences ") and http://msdn2.microsoft.com/en-us/library/5skw957f.aspx ("Mixing C (Structured) and C++ Exceptions") as well as http://msdn2.microsoft.com/en-us/library/ms680657.aspx ("Structured Exception Handling") for more general information.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 18817530
>>>> but I want to catch only exception that are Errors not every exception.
Generally, an exception can only be thrown by one of the statements in the try block or one of the functions called there. I would say any of these exceptions are errors cause otherwise they should have been handled before. Access violation is when using a NULL pointer or a pointer not initialized or a pointer already deleted. If you don't catch the error your program will stop anyway. I don't think it is a good idea to *handle*  (ignore) such a case. I would prefer if the program crashes thus giving a chance to correct the error. Or take a memory exception. If you don't get a new allocation, your prog can't do anything. It even can't handle the error. Or a division by 0? How will yo handle it? It should have been handled already. Then, STL throws some exceptions but always the same issue: if it wasn't handled directly where the STL function was called but at a higher level in the call stack, you definitively have no chance to handle it reasonably. You only can ignore - what is bad - or report and exit ("We are very sorry but the program has a failuer and we have to exit. Please excuse for any inconvenience" what might be less good than let it crash cause you suppress the error information of the operation system by doing so.

>>>> not every exception.
If you called a function in try block where you know that it might throw an exception the case is different. You then could check explicitly for one or more special exceptions:

try
{
       functionThat MightThrowSpecialException();
}
catch (SpecialException1 se1)
{
      // handle exceptiom
}
catch (SpecialException2 se2)
{
      // handle exception 2
}
catch(...)
{
     // handle all other exceptions
}

As told, I wouldn't make the last cath(...).

Regards, Alex



0
 
LVL 86

Expert Comment

by:jkr
ID: 18817826
>>// handle all other exceptions

You probably don't mind providing a working example that shows how to catch a SEH exception such as an Access Violation using a C++ catch handler without a translator, do you?
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:lussier
ID: 18818119
Hi jkr,

First thank you for your response. I've try to use __try in my code but I get this error :

Cannot use __try in functions that require object unwinding

This is my code : (I don't know if it can help you.)

__try
{
// Call  POL_Police.@WinC.Gestion polices.Onglets.Version polices  { ++Call  Field: FIELDS/+Function, FrameControl, ParentControl, .Local }
    v->ObIn_POLFFD04.ChildControl31.Index29 = v->FrameControl33.Index29;
    v->ObIn_POLFFD04.ChildControl31.Index230 = v->ParentControl32.Index230;

    ObCallMgr::Call(p_fnc_data, &v->ObIn_POLFFD04, &v->ObOut_POLFFD04, OB_RTDI_POLFFD04);
    v->Environment0.xReturned_status11 = v->st_returned;
} __except(1)
{
                     //*********
      ObMessage::Box(MB_OK,"Error!!");
      //*********
}
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 18818274
>>Cannot use __try in functions that require object unwinding

Yes, that's one slight inconventience with SEH handlers, but can easily be fixed by wrapping the '__try' frame around a function call like

__try
{
    GuardedFunction();
} __except(1)
{
                     //*********
      ObMessage::Box(MB_OK,"Error!!");
      //*********
}

void GuardedFunction()
{

// Call  POL_Police.@WinC.Gestion polices.Onglets.Version polices  { ++Call  Field: FIELDS/+Function, FrameControl, ParentControl, .Local }
    v->ObIn_POLFFD04.ChildControl31.Index29 = v->FrameControl33.Index29;
    v->ObIn_POLFFD04.ChildControl31.Index230 = v->ParentControl32.Index230;

    ObCallMgr::Call(p_fnc_data, &v->ObIn_POLFFD04, &v->ObOut_POLFFD04, OB_RTDI_POLFFD04);
    v->Environment0.xReturned_status11 = v->st_returned;
}

or just putting '__try' around the function that contains your above code.

Alternatively, try the approach using '_set_se_translator()' like

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 trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
{
    printf( "In trans_func.\n" );
    throw SE_Exception(pExp->ExceptionRecord.ExceptionCode);
}


//...

try
{

// Call  POL_Police.@WinC.Gestion polices.Onglets.Version polices  { ++Call  Field: FIELDS/+Function, FrameControl, ParentControl, .Local }
    v->ObIn_POLFFD04.ChildControl31.Index29 = v->FrameControl33.Index29;
    v->ObIn_POLFFD04.ChildControl31.Index230 = v->ParentControl32.Index230;

    ObCallMgr::Call(p_fnc_data, &v->ObIn_POLFFD04, &v->ObOut_POLFFD04, OB_RTDI_POLFFD04);
    v->Environment0.xReturned_status11 = v->st_returned;
}
catch( SE_Exception e )
{
    printf( "Caught a __try exception with SE_Exception.\n" );
}
0
 

Author Comment

by:lussier
ID: 18818832
HI,

I've try the first option >>or just putting '__try' around the function that contains your above code.
didn't work.

I've try the second one but I have some question. (because I'm a C++ beginner)

1) why there's a division by 0 in this function
void SEFunc()
{
    __try
    {
        int x, y=0;
        x = 5 / y;
    }
    __finally
    {
        printf( "In finally\n" );
    }
}

2) I understant that I should put the try around my code but did I keep this code too
 try
    {
        _set_se_translator( trans_func );
        SEFunc();
    }
    catch( SE_Exception e )
    {
        printf( "Caught a __try exception with SE_Exception.\n" );
    }

Thank you again
0
 
LVL 86

Expert Comment

by:jkr
ID: 18818898
>>1) why there's a division by 0 in this function

void SEFunc()
{
    __try
    {
        int x, y=0;
        x = 5 / y; // <--------- Here, 'y' is '0', making that 5 / 0
    }
}

>>2) I understant that I should put the try around my code but did I keep this
>>code too try

Now, that's a question on how the compiler generates the code that dispatches the exception to the correct catch handler. If that is done in a way that allows setting the translator func from within the code, that's fine, but I would not rely on it. Actually, I'd set the translator as early as possible.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

919 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

19 Experts available now in Live!

Get 1:1 Help Now