makecontext(3) - wariua/manpages-ko GitHub Wiki
makecontext, swapcontext - μ¬μ©μ λ¬Έλ§₯ μ‘°μνκΈ°
#include <ucontext.h>
void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
int swapcontext(ucontext_t *oucp, const ucontext_t *ucp);
μμ€ν
V κ³μ΄ νκ²½μμλ <ucontext.h>
μ ucontext_t
λΌλ νμ
μ΄ μμΌλ©° λ€ κ°μ§ ν¨μ getcontext(3), setcontext(3), makecontext()
, swapcontext()
λ₯Ό ν΅ν΄ ν νλ‘μΈμ€ λ΄μ μ¬λ¬ μ μ΄ μ€λ λλ€ μ¬μ΄μμ μ¬μ©μ μμ€ λ¬Έλ§₯ μ νμ΄ κ°λ₯νλ€.
κ·Έ νμ κ³Ό μμͺ½ λ ν¨μμ λν΄μ getcontext(3)λ₯Ό 보λΌ.
makecontext()
ν¨μλ (getcontext(3) νΈμΆμμ μ»μ) ucp
κ° κ°λ¦¬ν€λ λ¬Έλ§₯μ λ³κ²½νλ€. makecontext()
λ₯Ό νΈμΆνκΈ° μ μ νΈμΆμλ μ΄ λ¬Έλ§₯μ μν μ μ€νμ ν λΉνμ¬ κ·Έ μ£Όμλ₯Ό ucp->uc_stack
μ μ§μ ν΄μΌ νλ©° νμ λ¬Έλ§₯μ μ μνμ¬ κ·Έ μ£Όμλ₯Ό ucp->uc_link
μ μ§μ ν΄μΌ νλ€.
μ΄νμ (setcontext(3)λ swapcontext()
λ₯Ό μ΄μ©ν΄) μ΄ λ¬Έλ§₯μ νμ±νν λ ν¨μ func
κ° νΈμΆλλ©΄μ argc
λ€μμ μ€λ μΌλ ¨μ μ μ(int
) μΈμλ€μ΄ μ λ¬λλ€. νΈμΆμλ μ΄ μΈμλ€μ κ°μλ₯Ό argc
μ μ§μ ν΄μΌ νλ€. μ΄ ν¨μκ° λ°ννκ³ λλ©΄ νμ λ¬Έλ§₯μ΄ νμ±νλλ€. νμ λ¬Έλ§₯ ν¬μΈν°κ° NULLμ΄λ©΄ μ€λ λκ° λλλ€.
swapcontext()
ν¨μλ oucp
κ° κ°λ¦¬ν€λ ꡬ쑰체μ νμ¬ λ¬Έλ§₯μ μ μ₯ν λ€μ ucp
κ° κ°λ¦¬ν€λ λ¬Έλ§₯μ νμ±ννλ€.
μ±κ³΅ μ swapcontext()
λ λ°ννμ§ μλλ€. (νμ§λ§ λμ€μ oucp
κ° νμ±νλ λ λμμ¬ μλ μμΌλ©°, κ·Έ κ²½μ° swapcontext()
κ° 0μ λ°ννλ κ²μ²λΌ 보μΈλ€.) μ€λ₯ μ swapcontext()
λ -1μ λ°ννλ©° errno
λ₯Ό μ μ ν μ€μ νλ€.
ENOMEM
- λ¨μ μ€ν 곡κ°μ΄ μΆ©λΆνμ§ μμ.
glibcμμ λ²μ 2.1λΆν° makecontext()
λ° swapcontext()
λ₯Ό μ 곡νλ€.
μ΄ μ μμ μ¬μ©νλ μ©μ΄λ€μ λν μ€λͺ μ attributes(7)λ₯Ό 보λΌ.
μΈν°νμ΄μ€ | μμ± | κ° |
---|---|---|
makecontext() |
μ€λ λ μμ μ± | MT-Safe race:ucp |
swapcontext() |
μ€λ λ μμ μ± | MT-Safe race:oucp race:ucp |
SUSv2, POSIX.1-2001, POSIX.1-2008μμ μ΄μμ± λ¬Έμ λ₯Ό μ΄μ λ‘ makecontext()
λ° swapcontext()
λͺ
μΈλ₯Ό μ κ±°νμμΌλ©° λμ POSIX μ€λ λλ₯Ό μ¬μ©νκ² μμ©μ μ¬μμ±νκΈ°λ₯Ό κΆκ³ νκ³ μλ€.
ucp->uc_stack
μ ν΄μμ sigaltstack(2)μμμ λ§μ°¬κ°μ§μ΄λ€. μ¦, μ€νμ μ±μ₯ λ°©ν₯κ³Ό 무κ΄νκ² μ΄ κ΅¬μ‘°μ²΄μλ μ€νμΌλ‘ μ¬μ©ν λ©λͺ¨λ¦¬ μμμ μμμ κ³Ό κΈΈμ΄λ₯Ό λ΄λλ€. λ°λΌμ μ¬μ©μ νλ‘κ·Έλ¨μ΄ κ·Έ λ°©ν₯μ λν΄ μ κ²½μΈ νμκ° μλ€.
int
μ ν¬μΈν° νμ
μ΄ κ°μ ν¬κΈ°μΈ μν€ν
μ²μμλ (κ°λ Ή x86-32μμλ λ νμ
λͺ¨λ 32λΉνΈμ) makecontext()
μμ argc
λ€μμ μ€λ μΈμλ€λ‘ ν¬μΈν°λ₯Ό μ λ¬νλ κ²μ΄ μ΄μ°μ΄μ° κ°λ₯ν μλ μλ€. νμ§λ§ μ΄μμ±μ΄ 보μ₯λμ§ μκ³ νμ€μ λ°λ₯΄λ©΄ κ·μ λμ΄ μμ§ μμΌλ©° ν¬μΈν°κ° int
λ³΄λ€ ν° μν€ν
μ²μμ λμνμ§ μκ² λλ€. κ·ΈλΌμλ λΆκ΅¬νκ³ glibcμμ λ²μ 2.8λΆν° makecontext()
λ₯Ό μ‘°κΈ λ³κ²½ν΄μ μΌλΆ 64λΉνΈ μν€ν
μ²λ€(κ°λ Ή x86-64)μμ κ·Έλ κ² νλ κ²μ νμ©νλ€.
μλ μμ νλ‘κ·Έλ¨μ getcontext(3), makecontext()
, swapcontext()
μ¬μ© λ°©μμ λ³΄μ¬ μ€λ€. νλ‘κ·Έλ¨μ μ€ννλ©΄ λ€μ κ²°κ³Όκ° λμ¨λ€.
$ ./a.out
main: 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
main: exiting
#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");
}
int
main(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);
/* argc > 1 μλλ©΄ νμ λ¬Έλ§₯μ΄ func1() */
uctx_func2.uc_link = (argc > 1) ? NULL : &uctx_func1);
makecontext(&uctx_func2, func2, 0);
printf("main: swapcontext(&uctx_main, &uctx_func2)\n");
if (swapcontext(&uctx_main, &uctx_func2) == -1)
handle_error("swapcontext");
printf("main: exiting\n");
exit(EXIT_SUCCESS);
}
sigaction(2), sigaltstack(2), sigprocmask(2), getcontext(3), sigsetjmp(3)
2019-03-06