[R-pkg-devel] RFC: C backtraces for R CMD check via just-in-time debugging
Vladimir Dergachev
vo|ody@ @end|ng |rom m|nd@pr|ng@com
Tue Mar 12 03:10:20 CET 2024
On Tue, 12 Mar 2024, Ivan Krylov wrote:
> Vladimir,
>
> Thank you for the example and for sharing the ideas regarding
> symbol-relative offsets!
>
> On Thu, 7 Mar 2024 09:38:18 -0500 (EST)
> Vladimir Dergachev <volodya using mindspring.com> wrote:
>
>> unw_get_reg(&cursor, UNW_REG_IP, &pc);
>
> Is it ever possible for unw_get_reg() to fail (return non-zero) for
> UNW_REG_IP? The documentation isn't being obvious about this. Then
> again, if the process is so damaged it cannot even read the instruction
> pointer from its own stack frame, any attempts at self-debugging must
> be doomed.
Not sure. I think it just returns what is in it, you will get a false
reading if the stack is corrupted. The way that I see it - some printout
is better than none, and having signs that stack is badly corrupted is a
useful debugging clue.
>
>> * this should work as a package, but I am not sure whether the
>> offsets between package symbols and R symbols would be static or not.
>
> Since package shared objects are mmap()ed into the address space and
> (at least on Linux with ASLR enabled) mmap()s are supposed to be made
> unpredictable, this offset ends up not being static. On Linux, R seems
> to be normally built as a position-independent executable, so no matter
> whether there is a libR.so, both the R base address and the package
> shared object base address are randomised:
>
> $ cat ex.c
> #include <stdint.h>
> #include <R.h>
> void addr_diff(void) {
> ptrdiff_t diff = (char*)&addr_diff - (char*)&Rprintf;
> Rprintf("self - Rprintf = %td\n", diff);
> }
> $ R CMD SHLIB ex.c
> $ R-dynamic -q -s -e 'dyn.load("ex.so"); .C("addr_diff");'
> self - Rprintf = -9900928
> $ R-dynamic -q -s -e 'dyn.load("ex.so"); .C("addr_diff");'
> self - Rprintf = -15561600
> $ R-static -q -s -e 'dyn.load("ex.so"); .C("addr_diff");'
> self - Rprintf = 45537907472976
> $ R-static -q -s -e 'dyn.load("ex.so"); .C("addr_diff");'
> self - Rprintf = 46527711447632
>
>> * R ought to know where packages are loaded, we might want to be
>> clever and print out information on which package contains which
>> function, or there might be identical R_init_RMVL() printouts.
>
> That's true. Informaion on all registered symbols is available from
> getLoadedDLLs().
Ok, so this is reasonably straighforward.
best
Vladimir Dergachev
>
> --
> Best regards,
> Ivan
>
More information about the R-package-devel
mailing list