2017-06-30 82 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