我试图在x86-64上使用C ++和内联汇编(AT& T)实现上下文切换。
如果我保存并重新加载相同功能的上下文,它似乎正常工作
但是,当我尝试生成函数时,它在尝试加载第二个函数上下文后使用GDB给了我seg fault / corrupt堆栈。
例如,它打印
PRINT1
Print2
PRINT1
//损坏的堆栈和程序停止运行
但是,如果我在重新加载之前保存线程1(第一个函数)的上下文,那么就没有问题了。
例如,它打印
PRINT1
PRINT1
Print1
我正在为上下文保存和堆栈创建内存空间。保存上下文时,堆栈指针和基指针将保存到结构中。之后,堆栈指针将指向上下文存储器以推送寄存器值。
我想知道导致损坏堆栈的原因以及为什么我无法加载第二个函数的上下文。如果可能的话,请帮助我指出我的代码中的任何错误。谢谢!
childNodes[0]
答案 0 :(得分:0)
首先,当您在写入非早期clobber输出后读取输入时,您的第一个asm语句会覆盖rsp
未定义的值;对于这样的操作,它应该读取输出参数,curr_thd->stackptr
不应该是输入参数。
启动新线程时,代码不会切换到新堆栈,而是使用旧的线程堆栈。这解释了你的崩溃。
你的第二个asm语句恢复适合留下第一个asm语句的寄存器值,但是以堆栈状态退出并且指令指针适合留下第二个asm语句;这会导致未定义的行为。如果以某种方式复制该函数,它也将位于上下文切换函数的错误副本中。
GCC内联汇编程序不得更改不在输出或clobber列表中的寄存器的内容,也不能控制输入一个asm语句并留下另一个(在同一个线程中);这样做会导致未定义的行为。因此,保存上下文并恢复它不能是单独的asm语句。
您应该为上下文切换使用单个程序集块。特别是对于上下文切换,最简单的是避免内联汇编。