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