Exception handling techniques for C + + programs

Source: Internet
Author: User
Tags signal handler stack trace
Handling Exceptions in C + + has a slight implicit limitation at the language level, but in some cases you can bypass them. Learn a variety of ways to use anomalies and you can produce more reliable applications. Keep exception source information in C + +, whenever an exception is caught within a handler, the information about the source of the exception is unknown. The specific source of the exception can provide many important information to better handle the exception, or provide some information that can be attached to the error log for later analysis. To solve this problem, you can generate a stack trace in the constructor of the exception object during the throw exception statement. Exceptiontracer is a class that demonstrates this behavior. Listing 1. Generate a stack trace//Sample program in the exception object constructor:

COMPILER:GCC 3.2.3 20030502

linux:red Hat #include <execinfo.h>

#include <signal.h> #include <exception>

#include <iostream> using namespace std; Class Exceptiontracer

{

Public

Exceptiontracer ()

{

void * ARRAY[25];

int nSize = BackTrace (array, 25);

char * * symbols = backtrace_symbols (array, nSize);

 

for (int i = 0; i < nSize; i++)

{

cout << symbols[i] << Endl;

} free (symbols);

}

}; Governance signals every time a process executes a nasty action that makes Linux? The signal must be processed when the kernel sends a signal. Signal handlers usually release some important resources and terminate the application. In this case, all object instances on the stack are in the non-destructive state. On the other hand, if these signals are converted to C + + exceptions, you can gracefully call their constructors and arrange multi-layer catch blocks to better handle these signals. The Signalexceptionclass defined in Listing 2 provides an abstraction of a C + + exception that represents a possible signal from the kernel. Signaltranslator is a signalexceptionclass-based template class that is typically used to implement conversions to C + + exceptions. At any moment, there can be only one signal handler that processes a signal for an active process. Therefore, the Signaltranslator adopts the singleton design pattern. The overall concept was demonstrated through the Segmentationfault class for SIGSEGV and the Floatingpointexception class for SIGFPE. Listing 2. Convert signals to anomalies



Template <class signalexceptionclass> class Signaltranslator

{

Private

Class Singletontranslator

{

Public

Singletontranslator ()

{

Signal (Signalexceptionclass::getsignalnumber (),

Signalhandler);

} static void Signalhandler (int)

{

Throw Signalexceptionclass ();

}

}; Public

Signaltranslator ()

{

Static Singletontranslator S_objtranslator;

}

}; An example for SIGSEGV

Class Segmentationfault:public Exceptiontracer, public

exception

{

Public

static int Getsignalnumber () {return SIGSEGV;}

}; Signaltranslator<segmentationfault>

G_objsegmentationfaulttranslator; An example for SIGFPE

Class Floatingpointexception:public Exceptiontracer, public

exception

{

Public

static int Getsignalnumber () {return SIGFPE;}

}; Signaltranslator<floatingpointexception>

G_objfloatingpointexceptiontranslator; It is not possible for each ANSI C + + to catch an exception during the construction and destruction of the global (static global) variable when the exception is in the governance constructor and the destructor. Therefore, ANSI C + + does not recommend throwing exceptions in constructors and destructors for classes whose instances may be defined as global instances (static global instances). In other words, you should never define global (static global) instances for classes whose constructors and destructors might throw exceptions. However, assuming that there is a specific compiler and a specific system, it might be possible to do so, and fortunately for GCC on Linux, this is exactly the case. This can be demonstrated using the Exceptionhandler class, which also uses the singleton design pattern. Its constructor registers a handler that is not captured. Because only one unhandled handler can handle an active process at a time, the constructor should be called only once, so use singleton mode. You should define a global (static global) instance of Exceptionhandler before you define the actual global (static global) variable that has the problem. Listing 3. Handling exceptions in constructors class Exceptionhandler


{

Private

Class Singletonhandler

{

Public

Singletonhandler ()

{

Set_terminate (Handler);

} static void Handler ()

{

Exception from Construction/destruction of global variables try

{

Re-throw throw;

}

catch (Segmentationfault &)

{

cout << "Segmentationfault" << Endl;

}

catch (Floatingpointexception &)

{

cout << "Floatingpointexception" << Endl;

}

catch (...)

{

cout << "Unknown Exception" << Endl;

}//if this is a thread performing some core activity

Abort ();

else if this was a thread used to service requests

Pthread_exit ();

}

}; Public

Exceptionhandler ()

{

Static Singletonhandler S_objhandler;

}

}; Class A

{

Public

A ()

{

int i = 0, j = 1/i;

* (int *) 0 = 0;

}

}; Before defining any global variable, we define a dummy instance

of Exceptionhandler object to make sure that

Exceptionhandler::singletonhandler::singletonhandler () is

Invoked

Exceptionhandler G_objexceptionhandler;

A g_a; int main (int argc, char* argv[])

{

return 0;

Processing exceptions in a multithreaded program sometimes some exceptions are not caught, which causes the process to abort abnormally. Many times, however, a process contains multiple threads, where a few threads execute core application logic, while the remaining threads serve external requests. If a service thread does not handle an exception because of a programming error, it causes the entire application to crash. This may be unpopular because it facilitates denial-of-service attacks by sending an illegitimate request to the application. To avoid this, the catch handler can decide whether to request an exception abort call or a request thread to exit the call. This handler is shown at the end of the Exceptionhandler::singletonhandler::handler () function in Listing 3. Concluding remarks I briefly discussed a little C + + programming design pattern to better perform the following tasks: • Trace the source of the exception when throwing an exception.

• Converts a signal from a kernel program to a C + + exception.

• Catch exceptions thrown during the construction and/or destruction of global variables.

• Exception handling in multithreaded processes.

The above is the C + + program exception handling skills, more relevant articles please pay attention to topic.alibabacloud.com (www.php.cn)!

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.