/* * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
boolean isSupportedSigScenario ()
{ if ( (!strcmp(scenario, "nojvm")) || (!strcmp(scenario, "prepre")) || (!strcmp(scenario, "prepost")) ||
(!strcmp(scenario, "postpost")) || (!strcmp(scenario, "postpre")) )
{ // printf("%s is a supported scenario\n", scenario); returnTRUE;
} else
{
printf("ERROR: %s is not a supported scenario\n", scenario); returnFALSE;
}
}
boolean isSupportedSigMode ()
{ if ( (!strcmp(mode, "sigset")) || (!strcmp(mode, "sigaction")) )
{ // printf("%s is a supported mode\n", mode); returnTRUE;
} else
{
printf("ERROR: %s is not a supported mode\n", mode); returnFALSE;
}
}
int getSigNumBySigName(constchar* sigName)
{ int signals_len, sigdef_len, total_sigs, i=0;
if (sigName == NULL) return -1;
signals_len = sizeof(signals);
sigdef_len = sizeof(signalDefinition);
total_sigs = signals_len / sigdef_len; for (i = 0; i < total_sigs; i++)
{ // printf("Inside for loop, i = %d\n", i); if (!strcmp(sigName, signals[i].sigName)) return signals[i].sigNum;
}
return -1;
}
// signal handler void handler(int sig)
{
printf("%s: signal handler for signal %d has been processed\n", signal_name, signal_num);
sig_received = 1;
}
// Initialize VM with given options void initVM()
{
JavaVMInitArgs vm_args; int i =0;
jint result;
// Print the VM options in use
printf("initVM: numOptions = %d\n", vm_args.nOptions); for (i = 0; i < vm_args.nOptions; i++)
{
printf("\tvm_args.options[%d].optionString = %s\n", i, vm_args.options[i].optionString);
}
// Initialize VM with given options
result = JNI_CreateJavaVM( &vm, (void **) &env, &vm_args );
// Did the VM initialize successfully ? if (result != 0)
{
printf("ERROR: cannot create Java VM.\n"); exit(TEST_FAILED);
}
(*vm)->AttachCurrentThread(vm, (void **) &env, (void *) 0);
printf("initVM: JVM started and attached\n");
}
// Function to set up signal handler void setSignalHandler()
{ int retval = 0 ;
if (!strcmp(mode, "sigaction"))
{ struct sigaction act;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
retval = sigaction(signal_num, &act, 0); if (retval != 0) {
printf("ERROR: failed to set signal handler using function %s, error=%s\n", mode, strerror(errno)); exit(TEST_FAILED);
}
} // end - dealing with sigaction elseif (!strcmp(mode, "sigset"))
{ #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif
sigset(signal_num, handler); #ifdef __GNUC__ #pragma GCC diagnostic pop #endif
} // end dealing with sigset
printf("%s: signal handler using function '%s' has been set\n", signal_name, mode);
}
// Function to invoke given signal void invokeSignal()
{ int pid, retval;
sigset_t new_set, old_set;
pid = getpid();
retval = 0;
// we need to unblock the signal in case it was previously blocked by JVM // and as result inherited by child process // (this is at least the case for SIGQUIT in case -Xrs flag is not used). // Otherwise the test will timeout.
sigemptyset(&new_set);
sigaddset(&new_set, signal_num);
sigprocmask(SIG_UNBLOCK, &new_set, &old_set); if (retval != 0) {
printf("ERROR: failed to unblock signal, error=%s\n", strerror(errno)); exit(TEST_FAILED);
}
// send the signal
retval = kill(pid, signal_num); if (retval != 0)
{
printf("ERROR: failed to send signal %s, error=%s\n", signal_name, strerror(errno)); exit(TEST_FAILED);
}
// set original mask for the signal
retval = sigprocmask(SIG_SETMASK, &old_set, NULL); if (retval != 0) {
printf("ERROR: failed to set original mask for signal, error=%s\n", strerror(errno)); exit(TEST_FAILED);
}
printf("%s: signal has been sent successfully\n", signal_name);
}
// signal handler BEFORE VM initialization AND // Invoke signal BEFORE VM exits void scen_prepre()
{
setSignalHandler();
initVM();
invokeSignal();
(*vm)->DestroyJavaVM(vm);
}
// signal handler BEFORE VM initialization AND // Invoke signal AFTER VM exits void scen_prepost()
{
setSignalHandler();
initVM();
(*vm)->DestroyJavaVM(vm);
invokeSignal();
}
// signal handler AFTER VM initialization AND // Invoke signal BEFORE VM exits void scen_postpre()
{
initVM();
setSignalHandler();
invokeSignal();
(*vm)->DestroyJavaVM(vm);
}
// signal handler AFTER VM initializationAND // Invoke signal AFTER VM exits void scen_postpost()
{
initVM();
setSignalHandler();
(*vm)->DestroyJavaVM(vm);
invokeSignal();
}
// signal handler with no JVM in picture void scen_nojvm()
{
setSignalHandler();
invokeSignal();
}
void run()
{ // print the current scenario if (!strcmp(scenario, "postpre"))
scen_postpre(); elseif (!strcmp(scenario, "postpost"))
scen_postpost(); elseif (!strcmp(scenario, "prepre"))
scen_prepre(); elseif (!strcmp(scenario, "prepost"))
scen_prepost(); elseif (!strcmp(scenario, "nojvm"))
scen_nojvm();
}
// main main int main(int argc, char **argv)
{ int i=0, j;
signal_num = -1;
signal_name = NULL;
// Parse the arguments and find out how many vm args we have for (i=1; i<argc; i++)
{ if (! strcmp(argv[i], "-sig") )
{
i++; if ( i >= argc )
{
printUsage();
}
signal_name = argv[i];
} elseif (!strcmp(argv[i], "-mode"))
{
i++; if ( i >= argc )
{
printUsage();
}
mode = argv[i];
} elseif (!strcmp(argv[i], "-scenario"))
{
i++; if ( i >= argc )
{
printUsage();
}
scenario = argv[i];
} elseif (!strcmp(argv[i], "-vmopt"))
{
i++; if ( i >= argc )
{
printUsage();
}
numOptions++;
} else
{
printUsage();
}
}
if ( !isSupportedSigScenario() || !isSupportedSigMode() )
{
printUsage();
}
// get signal number by it's name
signal_num = getSigNumBySigName(signal_name); if (signal_num == -1)
{
printf("%s: unknown signal, perhaps is not supported on this platform, ignore\n",
signal_name); exit(TEST_PASSED);
}
j = 0; // Initialize given number of VM options if (numOptions > 0)
{
options = (JavaVMOption *) malloc(numOptions * sizeof(JavaVMOption)); for (i=0; i<argc; i++)
{ // parse VM options if (!strcmp(argv[i], "-vmopt"))
{
i++; if ( i >= argc )
{
printUsage();
}
options[j].optionString = argv[i];
j++;
}
}
}
// do signal invocation
printf("%s: start testing: signal_num=%d, mode=%s, scenario=%s\n", signal_name, signal_num, mode, scenario);
run();
while (!sig_received) {
sleep(1);
printf("%s: waiting for getting signal 1sec ...\n", signal_name);
}
printf("%s: signal has been received\n", signal_name);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.