I am developing a package to improve the debugging of Rcpp (C++) and SEXP based C code in gdb by providing convenience print, subset and other functions:
https://github.com/aryoda/R_CppDebugHelper I also want to solve the Windows-only problem that you can break into the debugger from R only via Rgui.exe (menu "Misc > break to debugger") by supporting breakpoints for R.exe. I want breakpoints support in R.exe because debugging in Rgui.exe has an unwanted side effect: https://stackoverflow.com/questions/59236579/gdb-prints-output-stdout-to-rgui-console-instead-of-gdb-console-on-windows-whe My idea is to break into the debugger from R.exe by calling a little C(++) code that contains an INT 3 (opcode 0xCC) SIGTRAP code: // break_to_debugger.cpp // [[Rcpp::export]] int break_to_debugger() { int a = 3; asm("int $3"); // this code line shall break into the debugger // Idea taken from "Rgui > break into debugger": // https://github.com/wch/r-source/blob/5a156a0865362bb8381dcd69ac335f5174a4f60c/src/gnuwin32/rui.c#L431 a++; return a; } # breakpoint.R #' breaks the execution into the debugger #' #' @return #' @export breakpoint <- function() { break_to_debugger() } Surprisingly this works not only on Linux but also on Windows (v10, x64 architecture = 64 bit) in Rterm.exe, but NOT for R.exe (64 bit): - Rgui.exe: Works - Rscript.exe: Works - R.exe: Does not work: R.exe is exited with: [Inferior 1 (process 20704) exited with code 020000000003] Can you please help me to understand why it works for Rgui.exe and Rscript.exe but not for R.exe? Why is int 3 exiting R.exe? And: How could I make it also work with R.exe? Thanks a lot for sharing your ideas and experiences! Jürgen PS 1: My sessionInfo(): R version 3.6.1 (2019-07-05) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 17134) PS 2: My package "CppDebugHelper" was compiled with -g -o0 -std=c++11 PS 3: Here is my captured gdb output for the three test cases: 1. Rgui.exe ------------------------------------------------------------------------ >gdb --quiet --args Rgui.exe --silent --vanilla Reading symbols from Rgui.exe...(no debugging symbols found)...done. (gdb) run Starting program: C:\R\bin\x64\Rgui.exe --silent --vanilla [New Thread 14476.0x3710] [New Thread 14476.0x284c] [New Thread 14476.0x50ec] [New Thread 14476.0x2d24] warning: Invalid parameter passed to C runtime function. [In RGui's R console:] library(CppDebugHelper) breakpoint() [in gdb again:] Program received signal SIGTRAP, Trace/breakpoint trap. break_to_debugger () at break_to_debugger.cpp:33 33 a++; (gdb) b debug_example_rcpp Breakpoint 1 at 0x66ac6846: file debug_example_rcpp.cpp, line 13. (gdb) continue Continuing. [In RGui's R console:] debug_example_rcpp() [in gdb again:] Breakpoint 1, debug_example_rcpp () at debug_example_rcpp.cpp:13 13 CharacterVector cv = CharacterVector::create("foo", "bar", NA_STRING, "hello") ; (gdb) next 14 NumericVector nv = NumericVector::create(0.0, 1.0, NA_REAL, 10) ; (gdb) n 16 DateVector dv = DateVector::create( 14974, 14975, 15123, NA_REAL); // TODO how to use real dates instead? (gdb) n 17 DateVector dv2 = DateVector::create(Date("2010-12-31"), Date("01.01.2011", "%d.%m.%Y"), Date(2011, 05, 29), NA_REAL); (gdb) n 18 DatetimeVector dtv = DatetimeVector::create(1293753600, Datetime("2011-01-01"), Datetime("2011-05-29 10:15:30") , NA_REAL); (gdb) n 19 DataFrame df = DataFrame::create(Named("name1") = cv, _["value1"] = nv, _["dv2"] = dv2); // Named and _[ ] are the same (gdb) n 20 CharacterVector col1 = df["name1"]; // get the first column (gdb) call dbg_print(df) (gdb) call dbg_str(df) (gdb) continue Continuing. [Output for the dbg_* function calls is printed to Rgui's R console (NOT the gdb terminal!):] name1 value1 dv2 1 foo 0 2010-12-31 2 bar 1 2011-01-01 3 <NA> NA 2011-05-29 4 hello 10 <NA> 'data.frame': 4 obs. of 3 variables: $ name1 : Factor w/ 3 levels "bar","foo","hello": 2 1 NA 3 $ value1: num 0 1 NA 10 $ dv2 : Date, format: "2010-12-31" "2011-01-01" ... 2. R.exe ------------------------------------------------------------------------ >gdb --quiet --args R.exe --silent --vanilla Reading symbols from R.exe...(no debugging symbols found)...done. (gdb) r Starting program: C:\R\bin\x64\R.exe --silent --vanilla [New Thread 20704.0x2b20] [New Thread 20704.0x4c08] [New Thread 20704.0x425c] [New Thread 20704.0x45f8] > library(CppDebugHelper) > breakpoint() [Thread 20704.0x45f8 exited with code 2147483651] [Thread 20704.0x425c exited with code 2147483651] [Thread 20704.0x4c08 exited with code 2147483651] [Inferior 1 (process 20704) exited with code 020000000003] (gdb) bt No stack. (gdb) 3. Rterm.exe ------------------------------------------------------------------------ gdb --quiet --args Rterm.exe --silent --vanilla Reading symbols from Rterm.exe...(no debugging symbols found)...done. (gdb) run Starting program: C:\R\bin\x64\Rterm.exe --silent --vanilla [New Thread 8132.0x3ee8] [New Thread 8132.0x3828] [New Thread 8132.0x4f1c] [New Thread 8132.0x4ff4] warning: Invalid parameter passed to C runtime function. [New Thread 8132.0x4dc8] > library(CppDebugHelper) > breakpoint() Program received signal SIGTRAP, Trace/breakpoint trap. break_to_debugger () at break_to_debugger.cpp:33 33 a++; (gdb) b debug_example_rcpp Breakpoint 1 at 0x66ac6846: file debug_example_rcpp.cpp, line 13. (gdb) c Continuing. [1] 4 > debug_example_rcpp() Breakpoint 1, debug_example_rcpp () at debug_example_rcpp.cpp:13 13 CharacterVector cv = CharacterVector::create("foo", "bar", NA_STRING, "hello") ; (gdb) n 14 NumericVector nv = NumericVector::create(0.0, 1.0, NA_REAL, 10) ; (gdb) n 16 DateVector dv = DateVector::create( 14974, 14975, 15123, NA_REAL); // TODO how to use real dates instead? (gdb) call dbg_print(nv) [1] 0 1 NA 10 (gdb) call dbg_print(dbg_subset(nv, 1, 2)) [1] 1 NA (gdb) ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel