makecontext(3) - wariua/manpages-ko GitHub Wiki

NAME

makecontext, swapcontext - μ‚¬μš©μž λ¬Έλ§₯ μ‘°μž‘ν•˜κΈ°

SYNOPSIS

#include <ucontext.h>

void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);

int swapcontext(ucontext_t *oucp, const ucontext_t *ucp);

DESCRIPTION

μ‹œμŠ€ν…œ 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κ°€ κ°€λ¦¬ν‚€λŠ” λ¬Έλ§₯을 ν™œμ„±ν™”ν•œλ‹€.

RETURN VALUE

성곡 μ‹œ swapcontext()λŠ” λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ”λ‹€. (ν•˜μ§€λ§Œ λ‚˜μ€‘μ— oucpκ°€ ν™œμ„±ν™”λ  λ•Œ λŒμ•„μ˜¬ μˆ˜λ„ 있으며, κ·Έ 경우 swapcontext()κ°€ 0을 λ°˜ν™˜ν•˜λŠ” κ²ƒμ²˜λŸΌ 보인닀.) 였λ₯˜ μ‹œ swapcontext()λŠ” -1을 λ°˜ν™˜ν•˜λ©° errnoλ₯Ό 적절히 μ„€μ •ν•œλ‹€.

ERRORS

ENOMEM
남은 μŠ€νƒ 곡간이 μΆ©λΆ„ν•˜μ§€ μ•ŠμŒ.

VERSIONS

glibcμ—μ„œ 버전 2.1λΆ€ν„° makecontext() 및 swapcontext()λ₯Ό μ œκ³΅ν•œλ‹€.

ATTRIBUTES

이 μ ˆμ—μ„œ μ‚¬μš©ν•˜λŠ” μš©μ–΄λ“€μ— λŒ€ν•œ μ„€λͺ…은 attributes(7)λ₯Ό 보라.

μΈν„°νŽ˜μ΄μŠ€ 속성 κ°’
makecontext() μŠ€λ ˆλ“œ μ•ˆμ „μ„± MT-Safe race:ucp
swapcontext() μŠ€λ ˆλ“œ μ•ˆμ „μ„± MT-Safe race:oucp race:ucp

CONFORMING TO

SUSv2, POSIX.1-2001, POSIX.1-2008μ—μ„œ 이식성 문제λ₯Ό 이유둜 makecontext() 및 swapcontext() λͺ…μ„Έλ₯Ό μ œκ±°ν•˜μ˜€μœΌλ©° λŒ€μ‹  POSIX μŠ€λ ˆλ“œλ₯Ό μ‚¬μš©ν•˜κ²Œ μ‘μš©μ„ μž¬μž‘μ„±ν•˜κΈ°λ₯Ό κΆŒκ³ ν•˜κ³  μžˆλ‹€.

NOTES

ucp->uc_stack의 해석은 sigaltstack(2)μ—μ„œμ™€ λ§ˆμ°¬κ°€μ§€μ΄λ‹€. 즉, μŠ€νƒμ˜ μ„±μž₯ λ°©ν–₯κ³Ό λ¬΄κ΄€ν•˜κ²Œ 이 κ΅¬μ‘°μ²΄μ—λŠ” μŠ€νƒμœΌλ‘œ μ‚¬μš©ν•  λ©”λͺ¨λ¦¬ μ˜μ—­μ˜ μ‹œμž‘μ κ³Ό 길이λ₯Ό λ‹΄λŠ”λ‹€. λ”°λΌμ„œ μ‚¬μš©μž ν”„λ‘œκ·Έλž¨μ΄ κ·Έ λ°©ν–₯에 λŒ€ν•΄ μ‹ κ²½μ“Έ ν•„μš”κ°€ μ—†λ‹€.

int와 포인터 νƒ€μž…μ΄ 같은 크기인 μ•„ν‚€ν…μ²˜μ—μ„œλŠ” (κ°€λ Ή x86-32μ—μ„œλŠ” 두 νƒ€μž… λͺ¨λ‘ 32λΉ„νŠΈμž„) makecontext()μ—μ„œ argc λ‹€μŒμ— μ˜€λŠ” μΈμžλ“€λ‘œ 포인터λ₯Ό μ „λ‹¬ν•˜λŠ” 것이 μ–΄μ°Œμ–΄μ°Œ κ°€λŠ₯ν•  μˆ˜λ„ μžˆλ‹€. ν•˜μ§€λ§Œ 이식성이 보μž₯λ˜μ§€ μ•Šκ³  ν‘œμ€€μ— λ”°λ₯΄λ©΄ κ·œμ •λ˜μ–΄ μžˆμ§€ μ•ŠμœΌλ©° 포인터가 int보닀 큰 μ•„ν‚€ν…μ²˜μ—μ„œ λ™μž‘ν•˜μ§€ μ•Šκ²Œ λœλ‹€. κ·ΈλŸΌμ—λ„ λΆˆκ΅¬ν•˜κ³  glibcμ—μ„œ 버전 2.8λΆ€ν„° makecontext()λ₯Ό 쑰금 λ³€κ²½ν•΄μ„œ 일뢀 64λΉ„νŠΈ μ•„ν‚€ν…μ²˜λ“€(κ°€λ Ή x86-64)μ—μ„œ κ·Έλ ‡κ²Œ ν•˜λŠ” 것을 ν—ˆμš©ν•œλ‹€.

EXAMPLE

μ•„λž˜ μ˜ˆμ‹œ ν”„λ‘œκ·Έλž¨μ€ 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);
}

SEE ALSO

sigaction(2), sigaltstack(2), sigprocmask(2), getcontext(3), sigsetjmp(3)


2019-03-06

⚠️ **GitHub.com Fallback** ⚠️