From: Dave H. <hel...@us...> - 2014-01-12 00:27:04
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "sfcb - Small Footprint CIM Broker". The branch, master has been updated via 8f807ce9ea1bc25d47c9490292f612d3824a8f4a (commit) from 88484a71630c60f380242a00e44d4655848f4478 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8f807ce9ea1bc25d47c9490292f612d3824a8f4a Author: Dave Heller <hel...@us...> Date: Sat Jan 11 19:13:20 2014 -0500 [sfcb-tix:#89] Gracefully handle providers doing abort() ----------------------------------------------------------------------- Summary of changes: contributions.txt | 2 + providerDrv.c | 66 ++++++++++++++++------- test/TestProviders/cmpiTestMethodProvider.c | 76 +++++++++++++++++++++++++++ test/schema/root/cimv2/Test_Method.mof | 1 + 4 files changed, 125 insertions(+), 20 deletions(-) diff --git a/contributions.txt b/contributions.txt index 1d55c32..1a74b5d 100644 --- a/contributions.txt +++ b/contributions.txt @@ -126,6 +126,8 @@ Klaus Kampf, Novell 09/30/2013 [sfcb-tix:#77] Fix prototype for stopBroker 10/01/2013 [sfcb-tix:#62] SIGSEGV in ClassProvider, return of 0 from addClParameter() not checked 10/31/2013 [sfcb-tix:#76] Identify running SFCB processes in ps output (contributions) +12/29/2013 [sfcb-tix:#90] Problems with enableInteroOp=false (contributions) +01/12/2014 [sfcb-tix:#89] Gracefully handle providers doing abort() (contributions) Mike Brasher, Inova ------------------- diff --git a/providerDrv.c b/providerDrv.c index 03f561b..6526925 100644 --- a/providerDrv.c +++ b/providerDrv.c @@ -165,14 +165,13 @@ unsigned long provSampleInterval = 10; unsigned long provTimeoutInterval = 25; unsigned provAutoGroup = 0; static int stopping = 0; +static int handlingError = 0; void uninitProvProcCtl(); extern void uninitSocketPairs(); extern void sunsetControl(); extern void uninitGarbageCollector(); -static BinResponseHdr *err_crash_resp; /* holds generic "we crashed" response */ -static long ecr_len; static long makeSafeResponse(BinResponseHdr *hdr, BinResponseHdr **out); typedef struct parms { @@ -472,19 +471,52 @@ static void handleSigPipe(int __attribute__ ((unused)) sig) static void -handleSigSegv(int __attribute__ ((unused)) sig) +handleSigError(int sig) { - Parms *threads = activeThreadsFirst; + Parms *threads = activeThreadsFirst; int dmy = -1; + /* prevent value from being optimized out so we can see it in call stack */ + char * volatile signame; - mlogf(M_ERROR, M_SHOW, - "-#- %s - %d provider exiting due to a SIGSEGV signal\n", - processName, currentProc); - while (threads) { - spSendResult(&threads->requestor, &dmy, err_crash_resp, ecr_len); - threads=threads->next; + if (handlingError) + goto end; + else + handlingError = 1; + + switch (sig) { + case (SIGABRT): + signame = "SIGABRT"; + break; + case (SIGSEGV): + signame = "SIGSEGV"; + break; + case (SIGFPE): + signame = "SIGFPE"; + break; + default: + signame = "UNKNOWN"; + break; } - abort(); /* force cord dump */ + + mlogf(M_ERROR, M_SHOW, "-#- %s - %d provider exiting due to a %s signal\n", + processName, currentProc, signame); + + if (threads) { + char msg[1024]; + snprintf(msg, 1023, "*** Provider %s(%d) exiting due to a %s signal", + processName, currentProc, signame); + BinResponseHdr *buf = errorCharsResp(CMPI_RC_ERR_FAILED, msg); + BinResponseHdr *resp; + long rlen = makeSafeResponse(buf, &resp); + + while (threads) { + spSendResult(&threads->requestor, &dmy, resp, rlen); + threads = threads->next; + } + } + abort(); /* force core dump */ + + end:; } static void @@ -894,7 +926,9 @@ getProcess(ProviderInfo * info, ProviderProcess ** proc) setSignal(SIGUSR1, handleSigUsr1, 0); setSignal(SIGUSR2, SIG_IGN,0); - setSignal(SIGSEGV, handleSigSegv, SA_ONESHOT); + setSignal(SIGSEGV, handleSigError, SA_ONESHOT); + setSignal(SIGABRT, handleSigError, SA_ONESHOT); + setSignal(SIGFPE, handleSigError, SA_ONESHOT); /* Label the process by modifying the cmdline */ extern void append2Argv(char *appendstr); @@ -970,14 +1004,6 @@ getProcess(ProviderInfo * info, ProviderProcess ** proc) _SFCB_ABORT(); } - char msg[1024]; - snprintf(msg,1023, "*** Provider %s(%d) exiting due to a SIGSEGV signal", - processName, currentProc); - BinResponseHdr* buf = errorCharsResp(CMPI_RC_ERR_FAILED, msg); - - ecr_len = makeSafeResponse(buf, &err_crash_resp); - free(buf); - processProviderInvocationRequests(info->providerName); _SFCB_RETURN(0); } diff --git a/test/TestProviders/cmpiTestMethodProvider.c b/test/TestProviders/cmpiTestMethodProvider.c index a7c920f..1eb87ed 100644 --- a/test/TestProviders/cmpiTestMethodProvider.c +++ b/test/TestProviders/cmpiTestMethodProvider.c @@ -1,5 +1,6 @@ #include <string.h> #include <stdio.h> +#include <signal.h> #include "cmpi/cmpidt.h" #include "cmpi/cmpift.h" #include "cmpi/cmpimacs.h" @@ -121,12 +122,87 @@ TestMethodProviderInvokeMethod(CMPIMethodMI * mi, * Adds a value of str2 string to out array argument */ rc = CMAddArg(out, argName, &val2, CMPI_string); + + /* + * For: 3048960 method array types not filled in Test provider. + */ } else if (!strcmp("CheckArrayNoType", methodName)) { data = CMGetArg(in, "IntArray", &rc); CMPIType atype=data.value.array->ft->getSimpleType(data.value.array,&rc); sprintf(result,"Datatype is %s",paramType(atype)); str1 = CMNewString(_broker, result, &rc); val1.string = str1; + + /* + * This method simulates various provider problems for testing. + */ + } else if (!strcmp("Misbehave", methodName)) { + data = CMGetArg(in, "Action", &rc); + + const char *strval = NULL; + if (data.type == CMPI_string && !(CMIsNullValue(data))) { + strval = CMGetCharsPtr(data.value.string, &rc); + sprintf(result, "data type is %s, value = %s", paramType(data.type), + strval); + + if (!strcmp(strval,"hang")) { + while(sleep(60)); /* to test req handler timeout, etc. */ + } + else if (!strcmp(strval,"abort")) { + abort(); + } + else if (!strcmp(strval,"fpe")) { + #pragma GCC diagnostic ignored "-Wdiv-by-zero" + fprintf(stderr,"ouch! %d\n",1/0); + #pragma GCC diagnostic warning "-Wdiv-by-zero" + } + else if (!strcmp(strval,"segfault")) { + void (*crashme)(void) = NULL; + crashme(); + } + /* + * These tend to behave as if the condition were raised internally + */ + else if (!strcmp(strval,"sigabrt")) { + kill(getpid(), SIGABRT); + while(sleep(3)); /* slight pause to ensure we catch signal */ + } + else if (!strcmp(strval,"sigfpe")) { + kill(getpid(), SIGFPE); + while(sleep(3)); + } + else if (!strcmp(strval,"sigsegv")) { + kill(getpid(), SIGSEGV); + while(sleep(3)); + } + else if (!strcmp(strval,"sigusr1")) { + kill(getpid(), SIGUSR1); /* as if we received a signal from stopBroker() */ + while(sleep(3)); + } + else if (!strcmp(strval,"sigkill")) { + kill(getpid(), SIGKILL); /* this is currently not handled by providerDrv*/ + while(sleep(3)); + } else { + sprintf(result, "Action not recognized: %s", strval); + fprintf(stderr, + "+++ cmpiTestMethodProvider: Action not recognized \"%s\"\n", + strval); + } + /* + * create the new string to return to client + */ + str1 = CMNewString(_broker, result, &rc); + val1.string = str1; + } + + } else { + sprintf(result, "Unknown method name: %s", methodName); + fprintf(stderr, + "+++ cmpiTestMethodProvider: Unknown method name \"%s\"\n", + methodName); + + str1 = CMNewString(_broker, result, &rc); + val1.string = str1; } } CMReturnData(rslt, (CMPIValue *) & val1, CMPI_string); diff --git a/test/schema/root/cimv2/Test_Method.mof b/test/schema/root/cimv2/Test_Method.mof index 58e6d5e..7365ba6 100644 --- a/test/schema/root/cimv2/Test_Method.mof +++ b/test/schema/root/cimv2/Test_Method.mof @@ -2,4 +2,5 @@ class Sample_Method { string SayHello( [IN] string Name, [OUT] string Message); string CheckArrayNoType( [IN] uint32 IntArray[], [OUT] string Message); + string Misbehave( [IN] string Action, [OUT] string Message); }; hooks/post-receive -- sfcb - Small Footprint CIM Broker |