2017-06-30 78 views
0

我正在爲自己開發一個R包,它使用rJava和使用Rcpp的C++代碼與Java代碼交互。雖然試圖調試Rsession崩潰Rstudio下工作使用LLDB時,我注意到,當我嘗試加載我開發包lddb輸出以下消息:爲什麼Rsession進程在SIGSEGV之後繼續以及它是什麼意思

(lldb) Process 19030 stopped 
* thread #1, name = 'rsession', stop reason = signal SIGSEGV: invalid address (fault address: 0x0) 
    frame #0: 0x00007fe6c7b872b4 
-> 0x7fe6c7b872b4: movl (%rsi), %eax 
    0x7fe6c7b872b6: leaq 0xf8(%rbp), %rsi 
    0x7fe6c7b872bd: vmovdqu %ymm0, (%rsi) 
    0x7fe6c7b872c1: vmovdqu %ymm7, 0x20(%rsi) 

(其中19030是rsession的PID)。在這一點上,Rstudio停止等待lldb恢復執行,但是不會在可怕的「R會話中止」彈出窗口中輸入lldb中的'c'命令來恢復rsession進程,並且Rstudio繼續順利進行,我可以使用沒有問題的加載包。即:

c 
Process 19030 resuming 

這到底是怎麼回事?爲什麼Rstudio的rsession不會崩潰,如果lldb說它已經「停止」了?這是由於R的(或Rstudio的?)SIGSEGV處理機制?這是否意味着最初的SIGSEGV是虛假的,不應該成爲令人擔憂的原因?當然(但這個問題可能不是主題):我如何理解lldb的輸出以確定加載我的軟件包時這個SIGSEGV是否應該進一步調試?

回答

0

SIGSEGV不會發生在Rsession的進程中,而是發生在rJava在包加載時啓動的JVM進程中。此行爲是已知的,並且由於JVM的內存管理,如上所述here

Java使用推測性加載。如果指針指向可尋址的 內存,則加載成功。很少的指針不指向 可尋址存儲器,並且所嘗試的負載生成SIGSEGV ...其中 Java運行時攔截,再次使存儲器尋址的,並重新啓動 加載指令。

所提出的解決方法GDB正常工作:

(gdb) handle SIGSEGV nostop noprint pass