[Rd] Why does INT 3 (opcode 0xCC) SIGTRAP break to debugger (gdb) in Rgui.exe and Rterm.exe but NOT in R.exe on Windows (64 bit)?
@osp@m m@iii@g oii @itieid-im@de
@osp@m m@iii@g oii @itieid-im@de
Wed Dec 11 21:42:56 CET 2019
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)
More information about the R-devel
mailing list