¿Cuáles son las formas productivas de depurar el código compilado de Rcpp cargado en R(en OS X Mavericks)?
debugging osx-mavericks (2)
¿Cuál es la forma más productiva y rápida de depurar objetos compartidos que se cargan en R, en particular en OS X Mavericks? Estoy interesado principalmente en la depuración de código Rcpp compilado.
He leído los externos de R en el código compilado de depuración ( http://cran.r-project.org/doc/manuals/R-exts.html#Debugging-compiled-code ) que favorece el uso de gdb, pero gdb no es oficialmente apoyado en Mavericks. Sin embargo, ¿parece que lldb es una alternativa viable? Encontré el recurso más útil para resolver cómo depurar el código compilado en R de la respuesta de Dirk a esta publicación (Gracias Dirk!) ( Depuración (línea por línea) de la DLL generada por Rcpp en Windows ).
Puedo depurar con éxito el código Rcpp compilado siguiendo los pasos que describo a continuación explícitamente paso a paso, que otros novatos de Rcpp pueden encontrar útil (disculpas por la extensión, pero creo que es mejor ser claro que omitir y ser vago). Pero este proceso de desarrollo es un poco tedioso y consume mucho tiempo.
Preguntas:
¿Existe una forma más rápida y / o más fácil de depurar el código Rcpp compilado, en comparación con lo que hago a continuación?
Soy un gran fan de Rstudio, y me encantaría incorporar objetos compartidos de depuración creados a partir de ese IDE, por lo que si alguien sabe cómo hacerlo, me gustaría saberlo. Rstudio parece usar atributos, y parece que el paso 4 a continuación necesita modificación, porque no parece haber un archivo .cpp en el directorio temporal después de compilarlo (en mi ejemplo a continuación, no hay un archivo "file5156292c0b48.cpp")
Los pasos:
1) (One off) Vaya al directorio ~ / .R (un directorio oculto con el.). Cree un nuevo archivo llamado "Makevars" y en él agregue la línea CXXFLAGS=-g -O0 -Wall
.
2) En el terminal, escriba R -d lldb
para iniciar R. lldb se iniciará ahora.
3) Escriba run
en la línea de comando lldb. Esto comenzará R.
4) Compile el código Rcpp y encuentre la ubicación de los objetos compilados. La respuesta de Dirk a la publicación mencionada anteriormente muestra una forma de hacerlo. Aquí hay un ejemplo que usaré aquí. Ejecuta los siguientes comandos en R:
library(inline)
fun <- cxxfunction(signature(), plugin="Rcpp", verbose=TRUE, body=''
int theAnswer = 1;
int theAnswer2 = 2;
int theAnswer3 = 3;
double theAnswer4 = 4.5;
return wrap(theAnswer4);
'')
Esto crea un objeto compartido compilado y otros archivos que se pueden encontrar ejecutando setwd (tempdir ()) y list.files () en R. Habrá un archivo .cpp, como "file5156292c0b48.cpp" y un archivo .so como " file5156292c0b48.so "
5) Cargue el objeto compartido en R ejecutando dyn.load("file5156292c0b48.so")
en la línea de comando R
6) Ahora queremos depurar el código C ++ en este objeto .so. Vuelve a lldb presionando ctrl + c
. Ahora quiero establecer un punto de ruptura en una línea específica en el archivo file5156292c0b48.cpp. Encuentro el número de línea correcto abriendo otra terminal y mirando el número de línea de interés en file5156292c0b48.cpp. Digamos que es la línea 31, que corresponde a la línea int theAnswer = 1; arriba en mi ejemplo. Luego escribo en la línea de comando lldb: breakpoint set -f file5156292c0b48.cpp -l 31
. El depurador imprime que se ha establecido un punto de interrupción y algunas otras cosas ...
7) Regrese a R ejecutando cont
en lldb (el indicador de R no aparece automáticamente para mí hasta que presione Intro) y active la función. Ejecute fun()
en la línea de comando R. Ahora estoy depurando el objeto compartido (pulse n para ir a la siguiente línea, p [nombre del objeto] para imprimir variables, etc.) ...
Esto es dificil Probé Xcode y Eclipse con una aplicación C ++ independiente, pero fue muy difícil hacer que todos los encabezados y bibliotecas funcionaran. Además, el código RcppExport llama a su función R real a través de un puntero que parecía confundir realmente a Xcode, y no pude entrar en mi función.
Terminé con (gdb o lldb): En R: R -d lldb
En el depurador, establezca el punto de interrupción: b functionName run
En R: .Call(etc) # or just call your R code which invokes compiled C/C++ code
en el depurador, una vez que ocurre la interrupción, puede pasar, examinar marcos, etc.
Esta referencia rápida del comando lldb / gdb ayudó mucho.
Olvídate de intentar hacer esto en una GUI en este punto. Esperemos que Rstudio se ponga en marcha.
Para depurar secuencias de comandos Rcpp simples como esta, una cosa que puede hacer es crear una aplicación .cpp
(con un main) que incruste R. De esta manera, puede depurarla directamente con Xcode, lo que le dará una buena experiencia de depuración.
Se vuelve más complicado cuando empiezas a querer depurar paquetes.