From: Brian Havard Date: Mon, 20 Aug 2001 16:10:57 +0000 (+0000) Subject: Catch exceptions in worker threads so a segfault doesn't kill all active X-Git-Tag: 2.0.25~255 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e9726a9667c4eaa56e25955004ac7c08f1580da1;p=apache Catch exceptions in worker threads so a segfault doesn't kill all active connections in the process. When this occurs, a graceful shutdown of the child is initiated so any leaked resources & hosed memory is disposed of ASAP. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90400 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/mpm/mpmt_os2/mpmt_os2.c b/server/mpm/mpmt_os2/mpmt_os2.c index 1c078badfa..1080251437 100644 --- a/server/mpm/mpmt_os2/mpmt_os2.c +++ b/server/mpm/mpmt_os2/mpmt_os2.c @@ -77,7 +77,6 @@ /* Todo list - Enforce MaxClients somehow - - Catch thread exceptions & initiate graceful shutdown of child process */ #define CORE_PRIVATE #define INCL_NOPMAPI diff --git a/server/mpm/mpmt_os2/mpmt_os2_child.c b/server/mpm/mpmt_os2/mpmt_os2_child.c index 36a96ca939..e9cfcecbe8 100644 --- a/server/mpm/mpmt_os2/mpmt_os2_child.c +++ b/server/mpm/mpmt_os2/mpmt_os2_child.c @@ -340,6 +340,39 @@ void add_worker() +ULONG APIENTRY thread_exception_handler(EXCEPTIONREPORTRECORD *pReportRec, + EXCEPTIONREGISTRATIONRECORD *pRegRec, + CONTEXTRECORD *pContext, + PVOID p) +{ + int c; + + if (pReportRec->fHandlerFlags & EH_NESTED_CALL) { + return XCPT_CONTINUE_SEARCH; + } + + if (pReportRec->ExceptionNum == XCPT_ACCESS_VIOLATION || + pReportRec->ExceptionNum == XCPT_INTEGER_DIVIDE_BY_ZERO) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, ap_server_conf, + "caught exception in worker thread, initiating child shutdown pid=%d", getpid()); + for (c=0; cservers[child_slot][c].tid == _gettid()) { + ap_scoreboard_image->servers[child_slot][c].status = SERVER_DEAD; + break; + } + } + + /* Shut down process ASAP, it could be quite unhealthy & leaking resources */ + shutdown_pending = 1; + ap_scoreboard_image->parent[child_slot].quiescing = 1; + DosUnwindException(UNWIND_ALL, 0, 0); + } + + return XCPT_CONTINUE_SEARCH; +} + + + static void worker_main(void *vpArg) { long conn_id; @@ -353,6 +386,10 @@ static void worker_main(void *vpArg) ULONG len; BYTE priority; int thread_slot = (int)vpArg; + EXCEPTIONREGISTRATIONRECORD reg_rec = { NULL, thread_exception_handler }; + + /* Trap exceptions in this thread so we don't take down the whole process */ + DosSetExceptionHandler( ®_rec ); rc = DosOpenQueue(&owner, &workq, apr_psprintf(pchild, "/queues/httpd/work.%d", getpid()));