所以正如标题所说,不幸的是,我的代码一直出现段错误。我很确定我正确地对所有内容进行了 malloc,并且我相信我的函数对于我拥有的测试用例是正确的,但它仍然存在段错误。我只是想看看是否有人可以发现为什么它可能是段错误?这是我到目前为止的代码:
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#include "t_lib.h"
#include <sys/mman.h>
struct ready_queue *ready;
struct tcb *running;
void t_yield()
{
tcb *tmp;
tmp->thread_context = running->thread_context;
running->thread_context = ready->head->thread_context;
ready->head->thread_context = tmp->thread_context;
swapcontext(ready->head->thread_context, running->thread_context);
}
void t_init()
{
tcb *tmp;
tmp = (tcb *) malloc(sizeof(tcb));
running = NULL;
ready->head = ready->tail = NULL;
}
void t_create(void (*fct)(int), int id, int pri)
{
size_t sz = 0x10000;
tcb *tmp;
tmp = (tcb *) malloc(sizeof(tcb));
ucontext_t *uc;
uc = (ucontext_t *) malloc(sizeof(ucontext_t));
tmp->thread_context = uc;
tmp->thread_priority = pri;
tmp->thread_id = id;
getcontext(uc);
uc->uc_stack.ss_sp = mmap(0, sz,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON, -1, 0);
uc->uc_stack.ss_size = sz;
uc->uc_stack.ss_flags = 0;
uc->uc_link = running->thread_context;
makecontext(uc, fct, 1, id);
if(running == NULL)
running = tmp;
else
{
if(ready->head == NULL)
{
ready->head = tmp;
ready->tail = tmp;
}
else
{
ready->tail->next = tmp;
ready->tail = tmp;
}
}
}
测试用例
void assign(int pri)
{
int i;
for (i = 0; i < 3; i++)
printf("in assign(1): %d\n", i);
t_yield();
for (i = 10; i < 13; i++)
printf("in assign(2): %d\n", i);
t_yield();
for (i = 20; i < 23; i++)
printf("in assign(3): %d\n", i);
}
int main(int argc, char **argv)
{
t_init();
t_create(assign, 1, 1);
printf("in main(): 0\n");
t_yield();
printf("in main(): 1\n");
t_yield();
printf("in main(): 2\n");
t_yield();
printf("done...\n");
return (0);
}
瓦尔格林结果:
==4596== Memcheck, a memory error detector
==4596== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==4596== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==4596== Command: ./test00
==4596==
==4596== Invalid write of size 8
==4596== at 0x400810: t_init (t_lib.c:24)
==4596== by 0x40072C: main (test00.c:24)
==4596== Address 0x8 is not stack'd, malloc'd or (recently) free'd
==4596==
==4596==
==4596== Process terminating with default action of signal 11 (SIGSEGV)
==4596== Access not within mapped region at address 0x8
==4596== at 0x400810: t_init (t_lib.c:24)
==4596== by 0x40072C: main (test00.c:24)
==4596== If you believe this happened as a result of a stack
==4596== overflow in your program's main thread (unlikely but
==4596== possible), you can try to increase the size of the
==4596== main thread stack using the --main-stacksize= flag.
==4596== The main thread stack size used in this run was 10485760.
==4596==
==4596== HEAP SUMMARY:
==4596== in use at exit: 0 bytes in 0 blocks
==4596== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==4596==
==4596== All heap blocks were freed -- no leaks are possible
==4596==
==4596== For counts of detected and suppressed errors, rerun with: -v
==4596== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)