我目前正在编写自己的线程库。而且我无法调试未处理的异常“堆栈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);
}
}
}
这是做旋转功能的主要功能,它应该运行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);
}
输出应该是5组4“spin1”和“spin2”交替。
SPIN1 SPIN1 SPIN1 SPIN1 spin2 spin2 spin2 spin2 SPIN1 ..
对于前两组“spin1”和1,代码完全正常,但在第二组“spin2”上给出了一个未处理的异常。我检查了存储和检索的堆栈指针,它们被正确存储和检索,链表存储和内存分配。更糟糕的是,我没有看到哪一行导致错误。
注意:我不允许使用任何线程系统调用,它必须在C中。
如果有帮助,这是我的TCB结构
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;
我很乐意分享我的源文件,如果它可以帮助你解决这个问题。
答案 0 :(得分:2)
简而言之,有些东西正在干扰堆栈cookie。
在执行功能代码之前,计算堆栈cookie并将其存储在当前堆栈帧的末尾。当功能代码执行结束时,它正在被验证。如果缓冲区溢出,它将被覆盖并且验证失败。这就是为什么它无法报告导致问题的原因。
在您的情况下,此异常可能有多种原因。由于在没有完整代码的情况下很难分辨,我会做出一些假设: