Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the getcontext system call (ucontext.h) really do?

I took operating systems last year, during which I used user contexts (defined in the header ucontext.h) to implement a thread scheduler (in which each thread simulated a process) for a project. I'm taking part in a lecture and will talk about user contexts, and it just occurred to me that, despite having done this project last year, I don't really understand what exactly the getcontext system call actually does.

The man pages for getcontext states that it

initializes the structure pointed at by ucp to the currently active context."

It also states, for the argument to setcontext, that if the ucp argument

was obtained by a call of getcontext(), program execution continues as if this call just returned.

Okay, so I understand that.

So here's what I'm confused about. Typically, for the way I learned it, to perform a context switch, one would initialize the ucontext_t struct and swap/set it as such:

ucontext_t ucp;
ucontext_t oucp;
getcontext(&ucp);

// Initialize the stack_t struct in the ucontext_t struct
ucp.uc_stack.ss_sp = malloc(STACK_SIZE);
ucp.uc_stack.ss_size = STACK_SIZE;
ucp.uc_stack.ss_flags = 0;

ucp.uc_link = /* some other context, or just NULL */;

// Don't block any signals in this context
sigemptyset(&ucp.uc_sigmask);
// Assume that fn is a function that takes 0 arguments and returns void
makecontext(&ucp, fn, 0);

// Perform the context switch. Function 'fn' will be active now
swapcontext(&oucp, &ucp);
// alternatively: setcontext(&ucp);

If I omit getcontext in smaller programs, nothing interesting happens. In somewhat larger programs in which there is more context switching via user contexts, I get a segmentation fault that is only resolved by adding getcontext back in.

What exactly does getcontext do? Why can't I just allocate a ucontext_t struct, initialize it by initializing the uc_stack and uc_sigmask fields, and calling makecontext without the getcontext? Is there some necessary initialization that getcontext performs that makecontext does not perform?

like image 893
kibibyte Avatar asked Oct 21 '13 20:10

kibibyte


People also ask

What does getContext do Linux?

The function getcontext() initializes the structure pointed to by ucp to the currently active context. The function setcontext() restores the user context pointed to by ucp. A successful call does not return.

What is Ucontext?

DESCRIPTION. The ucontext_t type is a structure type suitable for holding the context for a user thread of execution. A thread's context includes its stack, saved registers, and list of blocked signals. The ucontext_t structure contains at least these fields: ucontext_t *uc_link.


1 Answers

I looked at the GNU libc implementation for ucontext on x86/linux architectures, so, there might be different implementations for which the following does not hold.

The GNU libc manual states that:

The ucp parameter passed to the makecontext shall be initialized by a call to getcontext.

If you look at mcontext_t in glibc/sysdeps/unix/linux/x86/sys/ucontext.h there is a pointer to the floating point state (fpregset_t fpregs) that is initialized in getcontext() and dereferenced again in setcontext(). However, it is not initialized using makecontext(). I did a quick test with GDB and I got a segfault in setcontext() when trying to dereference the pointer to the floating point context in a ucontext_t struct not initialized by getcontext():

=> 0x00007ffff784308c <+44>: fldenv (%rcx)

like image 80
zgerd Avatar answered Sep 21 '22 19:09

zgerd