174 lines
6.9 KiB
HTML
174 lines
6.9 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta name="Copyright" content="Copyright (c) 2006 by IBM Corporation">
|
|
<title>Unhandled exceptions terminate the thread (not the process)</title>
|
|
<!-- Begin Header Records ========================================== -->
|
|
<!-- All rights reserved. Licensed Materials Property of IBM -->
|
|
<!-- US Government Users Restricted Rights -->
|
|
<!-- Use, duplication or disclosure restricted by -->
|
|
<!-- GSA ADP Schedule Contract with IBM Corp. -->
|
|
<!-- Change History: -->
|
|
<!-- YYMMDD USERID Change description -->
|
|
<!-- NETMG2 SCRIPT A converted by B2H R4.1 (346) (CMS) by HOLTJM at -->
|
|
<!-- RCHVMW2 on 29 Jan 1999 at 10:01:37 -->
|
|
<!--File Edited November 2001 -->
|
|
<!--End Header Records -->
|
|
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
|
|
</head>
|
|
<body>
|
|
<!-- Java sync-link -->
|
|
<script language="Javascript" src="../rzahg/synch.js" type="text/javascript">
|
|
</script>
|
|
|
|
<a name="Top_Of_Page"></a>
|
|
|
|
<h2>Unhandled exceptions terminate the thread (not the process)</h2>
|
|
|
|
<p>On a UNIX system, when an invalid or illegal software condition is
|
|
encountered (such as dividing by zero or using an invalid pointer), a signal is
|
|
generated. If the signal is not handled, the process is terminated.</p>
|
|
|
|
<p>The operating system does not generate a signal for these events, but instead, generates
|
|
an exception message. The exception message moves up the call stack,
|
|
allowing each stack frame (function on the stack or invocation entry) a chance
|
|
to handle the exception. Each function invocation may choose to handle or not
|
|
to handle the exception. If the exception is not handled, the message continues
|
|
to the next stack frame.</p>
|
|
|
|
<p>When the exception message reaches certain boundaries on the call stack
|
|
(like a main() entry point, usually called control boundaries) certain events
|
|
take place. These events include changing the exception to a different type,
|
|
terminating the process, terminating the activation group, or terminating the
|
|
thread. If an unhandled exception condition happens in a secondary thread and
|
|
moves all the way to the first invocation in the thread without being handled,
|
|
the resulting action will be to terminate the thread. During this percolation,
|
|
if the exception hits a control boundary and is not handled, it may terminate
|
|
the process.</p>
|
|
|
|
<p>A signal is never automatically generated for an exception message. When an
|
|
unhandled exception terminates the thread, Pthread cancellation cleanup
|
|
handlers and Pthread data destructors do not run and the thread is terminated
|
|
immediately with a return status of <strong>PTHREAD_EXCEPTION_NP</strong>.
|
|
<strong>PTHREAD_EXCEPTION_NP</strong> is a macro similar to the <strong>
|
|
PTHREAD_CANCELED</strong> macro, and is not NULL or a valid pointer.</p>
|
|
|
|
<p>On a UNIX system, this same activity may terminate the process due to the
|
|
signal that is generated.</p>
|
|
|
|
<p>In order to have your application terminate the process, when the exception
|
|
occurs, you must handle it and explicitly terminate the process. The following
|
|
example handles all hardware exceptions using the ANSI C signal model and uses
|
|
the Pthread signal SIGABRT to terminate the process.</p>
|
|
|
|
<p>You can also turn the exception message into a Posix signal and it may be
|
|
handled. See <a href="concep31.htm">Exceptions vs. Asynchronous signals vs.
|
|
ANSI C signals</a> for more information.</p>
|
|
|
|
<br>
|
|
<h3>Example</h3>
|
|
|
|
<p>See <a href="../apiref/aboutapis.htm#codedisclaimer">Code disclaimer information</a>
|
|
for information pertaining to code examples.</p>
|
|
|
|
<pre>
|
|
#define _MULTI_THREADED
|
|
#include <stdio.h>
|
|
#include <qp0z1170.h>
|
|
#include <time.h>
|
|
#include <signal.h>
|
|
#include <pthread.h>
|
|
#include "check.h"
|
|
|
|
|
|
void abortTheProcessWhenAnExceptionOccurs(int sigNumber);
|
|
void *threadfunc1(void *parm);
|
|
|
|
void *threadfunc1(void *parm)
|
|
{
|
|
char *p=NULL;
|
|
printf("Thread1: Unhandled exception (pointer fault) about to happen\n");
|
|
*p = `!';
|
|
printf("Thread1: After exception\n");
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void abortTheProcessWhenAnExceptionOccurs(int sigNumber) {
|
|
/* In a multithreaded environment this is a little difficult. We have to */
|
|
/* re-enable the ANSI C handler immediately, because that is the way it */
|
|
/* is defined. (A better alternative may be direct monitor exception */
|
|
/* handlers that are always valid in the function which they are */
|
|
/* registered, and with direct monitors, we can catch the hardware */
|
|
/* exception before it is converted to an ANSI C signal */
|
|
signal(SIGALL, abortTheProcessWhenAnExceptionOccurs);
|
|
/* Since ANSI C signals and hardware exceptions are only handled in */
|
|
/* the same thread that caused them, we send the Posix signal to */
|
|
/* the calling thread (The signal is delivered before returning from */
|
|
/* pthread_kill(). */
|
|
printf("Mapping ANSI signal %d to posix signal SIGABRT. "
|
|
"Aborting the process\n", sigNumber);
|
|
|
|
/* If we want to do some debug processing, we can put it here. */
|
|
pthread_kill(pthread_self(), SIGABRT);
|
|
return;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int rc=0;
|
|
pthread_t threadid;
|
|
void *status;
|
|
|
|
printf("----------- Setup Signal Mapping/Handling -------------\n");
|
|
printf("- Register ANSI C signal handler to map ALL\n"
|
|
" ANSI C signals & hardware exceptions to Posix signals\n");
|
|
/* If we want to do debug, or determine what when wrong a little more easily,
|
|
*/
|
|
/* we could use the abortTheProcessWhenAnExceptionOccurs function to delay
|
|
the thread, or */
|
|
/* dump failure data of some sort.
|
|
*/
|
|
signal(SIGALL, abortTheProcessWhenAnExceptionOccurs);
|
|
|
|
printf("----------- Start memory fault thread -------------\n");
|
|
printf("Create a thread\n");
|
|
rc = pthread_create(&threadid, NULL, threadfunc1, NULL);
|
|
checkResults("pthread_create()\n", rc);
|
|
|
|
rc = pthread_join(threadid, &status);
|
|
checkResults("pthread_join()\n", rc);
|
|
|
|
printf("Main completed\n");
|
|
return 0;
|
|
}
|
|
</pre>
|
|
|
|
<p><strong>Output:</strong></p>
|
|
|
|
<pre>
|
|
----------- Setup Signal Mapping/Handling -------------
|
|
- Register ANSI C signal handler to map ALL
|
|
ANSI C signals & hardware exceptions to Posix signals
|
|
----------- Start memory fault thread -------------
|
|
Create a thread
|
|
Thread1: Unhandled exception (pointer fault) about to happen
|
|
Mapping ANSI signal 5 to posix signal SIGABRT. Aborting the process
|
|
</pre>
|
|
|
|
<hr>
|
|
<center>
|
|
<table cellpadding="2" cellspacing="2">
|
|
<tr align="center">
|
|
<td valign="middle" align="center">
|
|
<a href="#Top_Of_Page">Top</a> |
|
|
<a href="rzah4mst.htm">Pthread APIs</a> |
|
|
<a href="aplist.htm">APIs by category</a></td>
|
|
</tr>
|
|
</table>
|
|
</center>
|
|
</body>
|
|
</html>
|
|
|