Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C线程调度(和asm)_C_Multithreading_Assembly_Variable Assignment - Fatal编程技术网

C线程调度(和asm)

C线程调度(和asm),c,multithreading,assembly,variable-assignment,C,Multithreading,Assembly,Variable Assignment,我目前正在编写自己的线程库。我无法调试未处理的异常“堆栈cookie检测代码检测到基于堆栈的缓冲区溢出”。下面是导致未处理异常的相关代码 void Scheduler() { void *curr_esp; TCB* next_thread = ready_queue->data; popFront(&ready_queue); __asm { pushad mov curr_esp, esp } curr_thread->esp = curr_

我目前正在编写自己的线程库。我无法调试未处理的异常“堆栈cookie检测代码检测到基于堆栈的缓冲区溢出”。下面是导致未处理异常的相关代码

void Scheduler()
{

  void *curr_esp;
  TCB* next_thread = ready_queue->data;
  popFront(&ready_queue);
  __asm
  {
pushad
mov curr_esp, esp
  }
  curr_thread->esp = curr_esp;

  if (curr_thread->status == RUNNING)
  {
    curr_thread->status = READY;
    Enqueue(curr_thread, &ready_queue);

  }

  curr_thread = next_thread;

  if (curr_thread->status == READY)
  {
    curr_thread->status = RUNNING;

    curr_esp = next_thread->esp;
__asm
{
  mov esp, curr_esp
  popad
}

 }

 else if (curr_thread->status == NEW)
 {
    curr_thread->status = RUNNING;
    curr_thread->params = (curr_thread->fn)(curr_thread->params);
    __asm
    {
      mov esp,curr_esp
    }
    if (curr_thread->status == RUNNING)
    {
       thread_exit(curr_thread->params);
    }

  }
}
这是执行spin函数的主要步骤,该函数应该运行threadlib,thd_yield基本上只调用我的调度程序

void *spin1(void *a)
{
    int i;
    for(i=0;i< 20; i++)
    {
        printf("SPIN1\n");
        if((i+1)%4==0)
            thd_yield();
    }
    return NULL;
}

void* spin2(void *a)
{
    int i;
    for(i=0;i< 20; i++)
    {
        printf("SPIN2\n");
        if((i+1)%4==0)
            thd_yield();
    }
    return NULL;
}


 int main()
{       
    thread_id_ id;
    thd_init();
    id = new_thd(spin2, NULL);
    spin1(NULL);
}

如果我的源文件能帮助您解决这个问题,我将很乐意与您分享。

简而言之,有东西干扰了堆栈cookie

堆栈cookie在执行函数代码之前计算并存储在当前堆栈帧的末尾。当函数代码执行结束时,将对其进行验证。如果缓冲区溢出,它将被覆盖,验证将失败。这就是为什么它不能向您报告导致问题的原因

在您的案例中,此异常可能有多种原因。由于没有完整的代码很难判断,我将做一些假设:

  • 实际上可能存在缓冲区溢出。测试的最后一种方法是禁用堆栈cookie安全检查,并查看是否存在“访问冲突”异常。即使没有,也可能是缓冲区溢出
  • 不同线程的堆栈指针指向重叠的内存区域。如果没有为堆栈分配足够的内存,可能会发生这种情况,这是一种缓冲区溢出
  • 不太可能,但您的代码可能是正确的,但它与堆栈cookie安全检查不兼容,因此您必须使其兼容或禁用该检查。这里唯一的建议是启用汇编器输出并检查它

这篇文章可能会给你一些线索,似乎这个问题的答案可能取决于你使用的编译器的版本以及编译时使用的选项。嗨!谢谢你的回答。如果可能的话,我可以把我的源文件发送给你吗?也许你能发现我几个小时都看不到的东西。我真的认为你的研究最好是自己发现它。我已经尝试了我能想到的一切,这就是为什么我在这里发帖。我通常能够调试自己的工作,但这真的让我感觉头撞到了墙上。我已经做了我能想到的一切。重写我的链表,重写整个计划程序(现在4次),使用内存诊断工具检查无意的内存分配和释放,所有这些都正确地签出。检查我通过asm操作的堆栈指针。我看不出有什么不对。@DanA:试着禁用堆栈cookies。您正在使用内联asm交换线程堆栈,所以我认为clover的第三点最有可能,堆栈检查可能会破坏您的正常代码。OTHH,在访问一些局部变量的代码中间交换ESP和EBP似乎很危险。一定要检查编译器生成的asm。您可能需要在asm中编写更多的上下文切换。
typedef struct _TCB_
{
  /* Unique ID*/
  thread_id_ id;
  /* Thread status*/
  enum ThreadState status;
  /* ID of next thread*/
  thread_id_ wait_id;

  void *esp;

  void *(*fn)(void*);

  void *params;

  void *stack;

}TCB;