GDB影响setcontext结果

时间:2014-10-06 16:36:28

标签: c gdb

我正在研究一些代码,这些代码要求我手动操作代码段的上下文然后切换到它,而不是使用makecontext。由于断言失败,我的测试程序失败了,所以我尝试使用GDB来确定结果并查看该部分失败的原因,但是,当我使用GDB v7.4.1运行它时,由于null而导致段错误在早期代码部分的地址。

上下文切换的结果如下:程序的指令指针指向函数的开头,该函数接收两个参数,指向另一个函数的指针和一些参数。 (该函数将参数传递给函数指针,然后将上下文切换回来)。

我隔离了引起此问题的代码区域,这是围绕该代码的代码的结果。

245 setcontext(runQueue->front->currContext);
(gdb) print runQueue->front->currContext->uc_mcontext.gregs[REG_RIP]
$1 = 420391
(gdb) print runQueue->front->currContext->uc_mcontext.gregs[REG_RSP]
$2 = 1077936128
(gdb) print runQueue->front->currContext->uc_mcontext.gregs[REG_RDI]
$3 = 4199321
(gdb) print runQueue->front->currContext->uc_mcontext.gregs[REG_RSI]
$4 = 10

这就在上下文切换之前。我检查了寄存器以验证程序切换到的上下文的值是否正确,并且它们是预期的(REG_RIP:4203091 == 0x402253,REG_RSP:1077936128 == 0x40400000,REG_RDI:4199321 == 0x401399,以及REG_RSI :0xa == 10)

进入上下文切换并在上下文中更改后,结果如下:

thread_func(function=0, arg=0x0) at thread.c:51
51 {
(gdb) info registers rip
rip      0x402253 0x402253 <thread_func>
(gdb) info registers rsp
rsp      0x40400000       0x40400000
(gdb) info registers rdi
rdi      0x401399 4199321
(gdb) info registers rsi
rsi      0xa      10

寄存器的值保持不变,但GDB没有正确传递参数,程序尝试使用0值,程序段错误用于访问空指针。

有没有办法解决这个问题或解决这个问题?

1 个答案:

答案 0 :(得分:2)

  

寄存器的值不变,但GDB没有正确传递参数,程序尝试使用0值,程序分段错误用于访问空指针。

您对所发生事件的解释极不可能是错误的。

特别是,您声称NULL解除引用似乎主要基于此:

thread_func(function=0, arg=0x0) at thread.c:51

其中function和arg的值应分别为0x4013990xa

但是,您的功能有一个序言,并且您已经在之前停止了该序言已执行。 GDB向您显示当前包含在内存位置的值,包含prolog之后的参数,但您还没有将它们存储在那里。尝试stepi过去的序言(过去的说明mov %rsi,-0x20(%rbp)),您会发现functionarg神奇地获得了正确的值。

如果你的程序后来崩溃了一个NULL指针取消引用,那就是因为别的事情而发生了。

P.S。在设置%rsp时,您违反了ABI要求:x86_84要求在每个函数内%rsp为16字节对齐。这意味着 on entry 到任何函数%rsp&0xF == 8(你有%rsp&0xF == 0)。这可能会导致以后崩溃,特别是如果您使用任何SSE2指令。

您可以通过将%rsp设置为mmap_addr+8,或将thread.c-mstackrealign一起编译来解决此问题。