神秘:MOV指令后,目的寄存器%RAX没有得到预期值(在内存中)(Mysterious: after

2019-10-23 09:21发布

生活充满了有趣的谜题,与他们搏斗让我闲扯...


最近我得到1个有趣段故障核心转储从正在运行的实例在虚拟机的x86-64 Linux操作系统(VMware的)。

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)尝试MOV%R8的内容从包含在%RAX地址,这引起故障段偏移16

信息寄存器表示RAX = 0,难怪段故障:),但是.....

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

但是,每指令0x42e0fa,RAX应包含timer->分组,这是不为0每下面存储器转储

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

所以让人不解的是,怎么可能RAX%的内容从存储在不同MOV指令后的第三个指令(0x42e0fa)

难道是缓存的问题? 难道是竞争状态?

这个函数调用的背景是发生在一个ukernel在Linux上,当ukernel被重新安排线程段发生故障。 只有一个硬件CPU线程可用。

文章来源: Mysterious: after mov instruction, destination register %rax did not get expected value (in memory)