C语言 在OS X 10.10操作系统中,出现了uncontext makecontext分段错误


#include <stdio.h>
#include <stdlib.h>
#define _XOPEN_SOURCE 600
#include <ucontext.h>
/* Tests creation.
   Should print "Hello World!" */
typedef struct thread_t{
  ucontext_t thread_context;
}thread_t;
void *thr1(void *in) {
  printf("Hello World!n");
  fflush(stdout);
  return NULL;
}
void *thr2(void *in) {
  printf("goodbye World!n");
  fflush(stdout);
  return NULL;
}
int main() {
  thread_t t1;
  thread_t t2;
  thread_create( &t1, thr1, NULL);
  // if you comment out the following line, the program will run like a charm. 
  thread_create( &t2, thr2, NULL);
  setcontext(&t1.thread_context);
  return EXIT_SUCCESS;
}
void thread_routine(void *(*start_routine)(void *), void *arg)
{
  start_routine(arg);
  printf("gtthread routine finishedn");
}
int thread_create(thread_t *thread,
        void *(*start_routine)(void *),
        void *arg){
  if (getcontext(&(thread->thread_context)) == -1)
  {
    perror("getcontext");
  }
  thread->thread_context.uc_stack.ss_sp = (char*) malloc(SIGSTKSZ);
  thread->thread_context.uc_stack.ss_size = SIGSTKSZ;
  thread->thread_context.uc_link = NULL;
  makecontext(&(thread->thread_context), thread_routine, 2, (void *)start_routine, arg);
}

我运行我的代码在OS X 10.10与gcc。我正在尝试实现一个usercontext库。

如果我注释掉thread_create( &t2, thr2, NULL);,代码将产生预期的效果。我不知道为什么与t2相关的一行会导致t1的分割故障。

<标题>作者的笔记h1> 换到Ubuntu后,我很高兴地实现了一个usercontext库。一切正常。不再有分段故障。不出所料,它在OS X 10.10上崩溃了。

我的猜测是,由于makecontext(), swapcontext()等在OS X上被弃用,因为编译器警告从10.6开始,我不应该期望它会工作。

您的程序有一些缺陷,其中一些导致它产生未定义的行为。未定义的行为可以被证明是你所期望的行为,但是如果它在某个特定的环境中发生了一次,那就没有任何理由期望它会再次发生——在那个环境中不会,当然也不会在不同的环境中。

以下是我注意到的更严重的问题:

  • thread_routine()对于上下文的开始函数没有正确的返回类型或参数类型。上下文启动函数预计返回void(即没有)而不是void *,这是完全不同的。此外,传递给它的实际参数(如果有的话)都将是类型int。因此,当您的程序作为setcontext()的结果调用此函数时,将导致未定义行为。在函数指针和对象指针的大小都与int相同的机器上,您可以这样做,但在其他机器上,程序可能会严重崩溃。

  • thread_create()中初始化thread->thread_context.uc_linkNULL。这本身并不是一个错误,但从更大的角度来看,当上下文的start函数返回时,它所运行的(OS)线程将退出。大概,您更希望有机会在不同的上下文中进行交换。

  • 使用setcontext()切换到t1上下文。如果成功,这个调用既不返回,也不返回,使您以后无法切换到t2上下文。但实际上,当t1的start函数返回时,线程和整个程序都会退出(见上文),所以这对您来说没有意义。无论如何,您应该使用swapcontext()

  • thread_create()声明返回int,但是没有return语句

顺便说一下,

gcc应该对其中一些问题发出警告。如果没有,那么就调高警告级别。-Wall级别应该是足够的,但我经常打开-Wextra来寻找问题。偶尔会有可以忽略的警告(特别是-Wextra),但是您应该对每个单独的警告分别进行评估。

我认为,你把"thread.h",为什么你使用线程如果你可以试试

相关内容

  • 没有找到相关文章

最新更新