Found because 'stress-ng --context 1 ...' always hangs.
The attached testcase uses the example from Linux swapcontext(3) to call
the context functions.
$ uname -r
3.6.0-0.419.g3c1308ed890e.x86_64
$ gcc -o ctxnosig ctxnosig.c
$ ./ctxnosig # ... and hit ^C
waste_time: started
[^C][SIGINT]
waste_time: returning, sigflag=1
main2: swapcontext(&uctx_main, &uctx_func2)
func2: started
func2: swapcontext(&uctx_func2, &uctx_func1)
func1: started
func1: swapcontext(&uctx_func1, &uctx_func2)
func2: returning
func1: returning
main2: exiting
waste_time: started
[^C][^C][^C][^C][^C][^C][^C][^C][^C][^C]...
waste_time: returning, sigflag=0
main: sleep(5)...
[SIGINT]
[SIGINT]
[^C][SIGINT]
main: sleep(5)=2
main: exiting, 4 SIGINT received
Possibly a minor issue because these functions are obsoleted (last seen
in POSIX 2004), but at least cygruby*.dll import these:
$ objdump -p /bin/cygruby320.dll | grep context
00378ca8 <none> 0286 getcontext
00378e08 <none> 0391 makecontext
003791c0 <none> 05cd swapcontext
...
--
Regards,
Christian
// BEGIN: example from Linux swapcontext(3)
#include <ucontext.h>
#include <stdio.h>
#include <stdlib.h>
static ucontext_t uctx_main, uctx_func1, uctx_func2;
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
static void
func1(void)
{
printf("func1: started\n");
printf("func1: swapcontext(&uctx_func1, &uctx_func2)\n");
if (swapcontext(&uctx_func1, &uctx_func2) == -1)
handle_error("swapcontext");
printf("func1: returning\n");
}
static void
func2(void)
{
printf("func2: started\n");
printf("func2: swapcontext(&uctx_func2, &uctx_func1)\n");
if (swapcontext(&uctx_func2, &uctx_func1) == -1)
handle_error("swapcontext");
printf("func2: returning\n");
}
static void
main2(int argc, char *argv[])
{
char func1_stack[16384];
char func2_stack[16384];
if (getcontext(&uctx_func1) == -1)
handle_error("getcontext");
uctx_func1.uc_stack.ss_sp = func1_stack;
uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
uctx_func1.uc_link = &uctx_main;
makecontext(&uctx_func1, func1, 0);
if (getcontext(&uctx_func2) == -1)
handle_error("getcontext");
uctx_func2.uc_stack.ss_sp = func2_stack;
uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
/* Successor context is f1(), unless argc > 1 */
uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1;
makecontext(&uctx_func2, func2, 0);
printf("main2: swapcontext(&uctx_main, &uctx_func2)\n");
if (swapcontext(&uctx_main, &uctx_func2) == -1)
handle_error("swapcontext");
printf("main2: exiting\n");
}
// END: example from Linux swapcontext(3)
//////////////////////////////////////////////////////////
#include <math.h>
#include <signal.h>
#include <unistd.h>
static volatile sig_atomic_t sigcnt, sigflag;
static void sighandler(int sig)
{
(void)sig;
++sigcnt;
sigflag = 1;
write(1, "[SIGINT]\n", 9);
}
static void waste_time()
{
printf("waste_time: started\n");
int flag = 0;
sigflag = 0;
volatile double x = 1.0;
const int n = 100*1000*1000; // ~5s on i7-14700
for (int i = 0; i < n && !flag; i++) {
x = asin(sin(x));
flag = sigflag;
}
printf("waste_time: returning, sigflag=%d\n", flag);
}
int main(int argc, char *argv[])
{
signal(SIGINT, sighandler);
waste_time(); // signals received
main2(argc, argv); // swapcontext example
waste_time(); // no signals received
printf("main: sleep(5)...\n");
printf("main: sleep(5)=%u\n", sleep(5)); // aborted by (new) signal (only)
printf("main: exiting, %d SIGINT received\n", sigcnt);
return 0;
}
--
Problem reports: https://cygwin.com/problems.html
FAQ: https://cygwin.com/faq/
Documentation: https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple