makecontext segfault? - PullRequest
       2

makecontext segfault?

2 голосов
/ 28 декабря 2010

Я работаю над домашним заданием, которое должно быть в следующем семестре. Это требует от нас реализации нашей собственной библиотеки переключения контекста / потоков с помощью API ucontext. Преподаватель предоставляет код, который делает это, но перед тем, как поток возвращается, он вручную выполняет некоторую работу и вызывает ISR, который находит другой поток для использования и обменивается с ним или, если его не осталось, завершается.

Смысл назначения состоит в том, чтобы использовать поле uc_link контекста, чтобы при достижении возврата он выполнял всю работу. Я создал функцию (типа void / void args), которая просто выполняет работу, которую выполняли функции раньше (очищает и затем вызывает ISR). Профессор сказал, что хочет этого.

Итак, все, что осталось, это сделать makecontext где-нибудь по пути в контексте в поле uc_link, чтобы он запускал мой поток, верно? Что ж, когда я делаю makecontext для, по-видимому, любой комбинации ucontext_t и функции, я получаю segfault, а gdb не помогает. Я могу пропустить makecontext, и моя программа существует «нормально», когда она достигает возврата в потоках, которые я создала, потому что ( предположительно) поле uc_link настроено неправильно (что я и пытаюсь сделать).

Я также не могу найти что-нибудь о том, почему makecontext будет сбоить. Кто-нибудь может помочь?

stack2.ss_sp = (void *)(malloc(STACKSIZE));
if(stack2.ss_sp == NULL){
printf("thread failed to get stack space\n");
exit(8);
}
stack2.ss_size = STACKSIZE;
stack2.ss_flags = 0;

if(getcontext(&main_context) == -1){
perror("getcontext in t_init, rtn_env");
exit(5);
}

//main_context.uc_stack = t_state[i].mystk;                                                                                                                
main_context.uc_stack = stack2;
main_context.uc_link = 0;
makecontext(&main_context, (void (*)(void))thread_rtn, 0);

Я также пробовал только thread_rtn, & thread_rtn и другие вещи. thread_rtn объявляется как void thread_rtn (void).

позже, в каждой теме. run_env имеет тип ucontext_t: ...

t_state[i].run_env.uc_link = &main_context;

1 Ответ

0 голосов
/ 13 апреля 2011

Здесь много чего происходит, но я выскажу свои лучшие мысли.Я также пытаюсь ответить на вопрос, не решая домашнее задание.

В каком контексте объявлен thread_rtn и используются ли в нем какие-либо нестатические переменные?
Сегфоут, вероятно, вызван памятью, которая былавыделен, но больше недоступен (вне контекста или освобожден).

Я не могу сказать, совпадает ли main_context с контекстом потока, они должны отличаться.

Похоже, что каждому потоку нужен свой собственный стек, который не должен совпадать со стеком основного контекста (или сэмом, как стек любого другого потока).Подумайте, где каждый поток может получить память для использования в качестве стека.При каких условиях malloc(STACKSIZE) возвращает NULL?

Когда контекст потока добавляется в основной контекст, main_context.uc_link следует увеличивать.Похоже, что main_context.uc_link отслеживает, сколько потоков связано с основным контекстом.Подумайте о том, что происходит, когда счет уменьшается (я пытаюсь оставить некоторую работу, имеющую отношение к курсу, а не говорю, что делать с уменьшением счета).Обратите внимание на специальное значение 0, означающее, что больше нет потоков, связанных с этим основным контекстом.Есть ли максимальное значение для main_context.uc_link?

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...