神秘:在mov指令之后,目标寄存器%rax没有得到预期值(在内存中)

时间:2015-06-14 03:22:21

标签: linux multithreading caching timer

生活充满了有趣的谜题,与他们搏斗让我咯咯地笑......

最近我从vm(vmware)中运行实例x86-64 linux获得了一个有趣的段故障核心转储。

mov 0x18(%rdi) %rax // move a pointer to %rax, trick things happens here 
                       it seems rax did not get expected value at all
...// 2 instructions later
mov %r8,0x10(%rax)  // load some value to offset of the pointer in memory

详情如下。

Segment fault
Dump of assembler code for function timer_delink:
// Function: boolean timer_delink(timer_t *timer), where timer is a cycle link list(prev/next never NULL)
  0x42e0f0 <+0>:     mov    (%rdi),%rcx                       rdi <= timer; rcx <= timer->parent
  0x42e0f3 <+3>:     xor    %eax,%eax                         eax <= update_parent <= 0; eax stores return value
  0x42e0f5 <+5>:     test   %rcx,%rcx                         if (!timer->parent)  return(FALSE);
  0x42e0f8 <+8>:     je     0x42e138 <timer_delink+72>        return eax(update_parent);
  0x42e0fa <+10>:    mov    0x18(%rdi),%rax                   rax <= timer->prev             //rax should contain timer->prev, which is 
  0x42e0fe <+14>:    mov    0x10(%rdi),%r8                    r8  <= timer->next
  0x42e102 <+18>:    mov    0x8(%rcx),%rdx                    rdx <= timer->parent->down
=>0x42e106 <+22>:    mov    %r8,0x10(%rax)                    timer->rev->next = timer->next;//info register said rax = 0;
  0x42e10a <+26>:    mov    0x10(%rdi),%rsi                   rsi <= timer->next
  0x42e10e <+30>:    mov    %rax,0x18(%rsi)                   timer->next->prev = timer->prev;
  0x42e112 <+34>:    xor    %eax,%eax                         eax <= update_parent <= 0

在违规指令(0x42e106)中尝试将%r8的内容移动到%rax中包含的地址偏移16,这导致了段错误

信息寄存器说rax = 0,难怪为什么段故障:),但是......

  (gdb) info register
  rax            0x0      0       
  ..
  rdi            0x20103ff0       ==> stores timer pointer

但是根据指令0x42e0fa,rax应该包含timer-&gt; prev,在每个内存转储下面不是0

(gdb) p *timer
    $8 = {parent = 0x2f379e0 <root_timer>, down = 0x0, next = 0x201027c0, prev = 0x20103b28 ...}

难题是,%rax的内容与mov指令后的第3条指令的内存有何不同(0x42e0fa)

可能是缓存问题吗? 这可能是竞争条件吗?

此函数调用的上下文发生在linux上的ukernel中,当ukernel重新调度线程时会发生段错误。 只有一个硬件CPU线程可用。

0 个答案:

没有答案