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