1

所以正如标题所说,不幸的是,我的代码一直出现段错误。我很确定我正确地对所有内容进行了 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)
4

1 回答 1

0

在函数t_yield 中,您使用了未初始化的指针tmp

tcb *tmp;   // <- definition without initialization
tmp->thread_context = running->thread_context; // <- using
于 2017-09-29T17:14:11.993 回答