C线程调度(和asm)
我目前正在编写自己的线程库。我无法调试未处理的异常“堆栈cookie检测代码检测到基于堆栈的缓冲区溢出”。下面是导致未处理异常的相关代码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_
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安全检查不兼容,因此您必须使其兼容或禁用该检查。这里唯一的建议是启用汇编器输出并检查它
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;