I often use C level debuggers such as lldb and gdb when debugging R
packages with compiled code. If you are unfamiliar with doing this Kevin Ushey
has an excellent
post on the topic.
Usually bugs are reproducible both from the R terminal and RStudio. If this is
the case then running R under the debugger is easy; just start R from the
R -d lldb.
However more rarely there will be a bug that only occurs when the code is run in RStudio, and in these cases you would ideally like to be able to attach to the internal RStudio Rsession process.
You can get the PID (process identifier) of any R process by calling
Sys.getpid() from the
R console. Then you can have the debugger attach to this PID with the
argument to lldb, e.g.
lldb -p 45323. However if you do this with the current
RStudio release (v1.1) you will get this!
I believe this occurs because of how RStudio detects if the R process is still running. When the debugger interrupts internal rsession process RStudio no longer thinks it has an active R session running, so shows the error message.
However you can work around this by using a feature of lldb I hadn’t used until
encountering this problem,
--waitfor. This allows you to have lldb attach to
a process (by name) as soon as it starts.
To do this first start lldb from a separate console (
lldb). This will launch
you into the lldb prompt. Then tell lldb you would like to attach to the
rsession process using
process attach --name rsession --waitfor
lldb will then wait for this rsession process to start. Now we can start up RStudio. The lldb session will then print something like the following
Process 50879 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP frame #0: 0x000000010085b4f8 rsession`rstudio_boost::filesystem::path::path<char const*>(char const*, char const*) + 88 rsession`rstudio_boost::filesystem::path::path<char const*>: -> 0x10085b4f8 <+88>: movb %al, (%r13) 0x10085b4fc <+92>: jmp 0x10085b50c ; <+108> 0x10085b4fe <+94>: movq %r13, %rdi 0x10085b501 <+97>: movq %r12, %rsi Target 0: (rsession) stopped.
And the RStudio session will be stopped with RStudio only partially loaded. You can then
continue execution in lldb with
c and the RStudio session will continue to load.
From here you can set breakpoints / interrupt execution as you normally would
when debugging with lldb.
While this process isn’t too cumbersome, it is certainly more work than is ideal, and the workaround is somewhat esoteric. Luckily, RStudio 1.2+ (now available as a preview release) makes this extra workaround unnecessary! In v1.2 you can attach lldb directly to a running RStudio session without causing RStudio to fail!
Thanks again to Jonathan McPherson and Kevin Ushey for their pointers on how get this working for RStudio 1.1.