diff --git a/var/spack/repos/builtin/packages/libsigsegv/package.py b/var/spack/repos/builtin/packages/libsigsegv/package.py index 7aab695b761..b62fded72b0 100644 --- a/var/spack/repos/builtin/packages/libsigsegv/package.py +++ b/var/spack/repos/builtin/packages/libsigsegv/package.py @@ -3,6 +3,8 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import llnl.util.tty as tty + from spack import * @@ -18,5 +20,28 @@ class Libsigsegv(AutotoolsPackage, GNUMirrorPackage): patch('patch.new_config_guess', when='@2.10') + test_requires_compiler = True + def configure_args(self): return ['--enable-shared'] + + def test(self): + # Start by compiling and linking the simple program + prog = 'data/smoke_test' + + options = [ + '-I{0}'.format(self.prefix.include), + '{0}.c'.format(prog), + '-o', + prog, + '-L{0}'.format(self.prefix.lib), + '-lsigsegv', + '-Wl,-R{0}'.format(self.prefix.lib)] + reason = 'test ability to link to the library' + self.run_test('cc', options, [], None, False, purpose=reason) + + # Now run the program and confirm the output matches expectations + with open('./data/smoke_test.out', 'r') as fd: + expected = fd.read() + reason = 'test ability to use the library' + self.run_test(prog, [], expected, None, False, purpose=reason) diff --git a/var/spack/repos/builtin/packages/libsigsegv/test/smoke_test.c b/var/spack/repos/builtin/packages/libsigsegv/test/smoke_test.c new file mode 100644 index 00000000000..80bfb765fab --- /dev/null +++ b/var/spack/repos/builtin/packages/libsigsegv/test/smoke_test.c @@ -0,0 +1,67 @@ +/* Simple "Hello World" test set up to handle a single page fault + * + * Inspired by libsigsegv's test cases with argument names for handlers + * taken from the header files. + */ + +#include "sigsegv.h" +#include +#include /* for exit */ +# include /* for NULL on SunOS4 (per libsigsegv examples) */ +#include /* for controlling handler-related flow */ + + +/* Calling environment */ +jmp_buf calling_env; + +char *message = "Hello, World!"; + +/* Track the number of times the handler is called */ +volatile int times_called = 0; + + +/* Continuation function, which relies on the latest libsigsegv API */ +static void +resume(void *cont_arg1, void *cont_arg2, void *cont_arg3) +{ + /* Go to calling environment and restore state. */ + longjmp(calling_env, times_called); +} + +/* sigsegv handler */ +int +handle_sigsegv(void *fault_address, int serious) +{ + times_called++; + + /* Generate handler output for the test. */ + printf("Caught sigsegv #%d\n", times_called); + + return sigsegv_leave_handler(resume, NULL, NULL, NULL); +} + +/* "Buggy" function used to demonstrate non-local goto */ +void printit(char *m) +{ + if (times_called < 1) + /* Force SIGSEGV only on the first call. */ + printf("%s\n", *m); + else + /* Print it correctly. */ + printf("%s\n", m); +} + +int +main(void) +{ + /* Install the global SIGSEGV handler */ + sigsegv_install_handler(&handle_sigsegv); + + char *msg = "Hello World!"; + int calls = setjmp(calling_env); /* Resume here after detecting sigsegv */ + + /* Call the function that will trigger the page fault. */ + printit(msg); + + return 0; +} diff --git a/var/spack/repos/builtin/packages/libsigsegv/test/smoke_test.out b/var/spack/repos/builtin/packages/libsigsegv/test/smoke_test.out new file mode 100644 index 00000000000..31071777e2b --- /dev/null +++ b/var/spack/repos/builtin/packages/libsigsegv/test/smoke_test.out @@ -0,0 +1,2 @@ +Caught sigsegv #1 +Hello World!