gpt4 book ai didi

C线程调度(和asm)

转载 作者:行者123 更新时间:2023-11-30 18:47:53 25 4
gpt4 key购买 nike

我目前正在编写自己的线程库。而且我无法调试未处理的异常“堆栈 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 的 spin 函数,并且 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”交替出现。

旋转1自旋1自旋1自旋1自旋2自旋2自旋2自旋2自旋1..

该代码对于前 2 组“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;

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

最佳答案

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

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

在您的情况下,可能有多种原因导致此异常。由于没有完整的代码很难判断,我将做出一些假设:

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

关于C线程调度(和asm),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47248238/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com