2014年10月30日 星期四

Illegal instruction 追蹤

某天執行程式的時候遇到Illegal instruction,這時候如果執行
# dmesg
應該會看到類似如下的訊息
XXXX[4444] trap invalid opcode rip:42a016 rsp:415104b8 error:0


這個問題通常是因為程式使用了CPU不支援的instruction set(也有例外),那我們要怎麼知道是使用到哪個instruction(opcode)呢?

1. 開啟core dump
  Ubuntu預設是不會產生core dump file的,要讓系統產生必須執行下面的指令
# ulimit -c unlimited

  在執行後,當遇到Illegal instruction的錯誤時,在執行的資料夾應該會出現core.XXX的檔案及為core dump file了

2. 使用gdb追蹤
  使用gdb 可以讓我們知道在哪邊發生了錯誤
  # gdb [程式]  [core dump file]

  以我遇到的例子如下:
  Program terminated with signal 4, Illegal instruction.
  #0  0x000000000042a016 in FUNCTION_NAME ()
  我們就可以發現錯誤是在 0x000000000042a016的地方

3. 檢視assembly code
   同樣在gdb裡面執行 
  (gdb) disassemble FUNCTION_NAME

0x000000000042a00d <blake2b_init_param_avx+45>: cmp    %rax,%rdx
0x000000000042a010 <blake2b_init_param_avx+48>: jbe    0x42a0c0 <blake2b_init_param_avx+224>
0x000000000042a016 <blake2b_init_param_avx+54>: vmovdqu (%rsi),%xmm1

就可以發現到底是什麼instruction造成錯誤了。