[Rd] load/unload segfault puzzle

Rory Winston rory.winston at gmail.com
Fri Jun 14 00:48:55 CEST 2013


Bill

Hadn't thought of that - great idea. I wonder if it would be possible to run R under gdb and trap the segfault - this should give the invalid address in the backtrace - and then grep the process map for that address?

Cheers 
-- Rory

Sent from my iPhone

On 14 Jun 2013, at 00:34, William Dunlap <wdunlap at tibco.com> wrote:

> You can also read the process map table in /proc/<pid>/maps to see which
> shared object is associated with the illegal address that valgrind identified.
> Read the map table after each load or unload of a *.so with
>   map <- readProcessMaps()
> and use something like
>   subset(map, startAddr <= badAddr & badAddr < endAddr)
> to see where the bad address  is.  The "<BSS>" lines are uninitialized memory
> required by a shared object (or executable), I believe the object mentioned
> in the previous line.  A shared object may have a _fini procedure that refers to
> an address in a shared object that got unloaded (_fini might call C++ destructors).
> 
> Here is some code to read the map table for the current process.  I did a quick
> check of the code on both 32- and 64-bit Linux.  My 32-bit machine does not
> have a recent version of R on it so there is some wierd code to work around that.
> 
> readProcessMaps <- function()
> {
>    # Read /proc/$CWD/maps into a data.frame.  This shows which
>    # memory addresses are associated with which shared objects
>    # at the current time.
>    #
>    # there are some hacks to make this work in R-2.10.1 (2009), the only
>    # version I have compiled for 32-bit Linux.
>    #   * as.hexmode() only accepted a scalar
>    #   * read.table() did not have a text= argument
>    txt <- readLines(file.path("/proc", Sys.getpid(), "maps"))
>    nFields <- count.fields(textConnection(txt))
>    txt[nFields == 5] <- paste(txt[nFields == 5], "<BSS>")
>    txt <- sub("-", " ", txt)
>    colNames <- c("startAddr", "endAddr", "perms", "offset", "dev", "inode", "pathname")
>    # retval <- read.table(text=txt, col.names=colNames, colClasses="character")
>    retval <- read.table(textConnection(txt), col.names=colNames, colClasses="character")
>    hex64StringToDouble <- function(s) {
>        # as.hexmode only works up to 2^31-1, so we
>        # convert 64-bit address nibble by nibble into a double.
>        n <- nchar(s)
>        acc <- numeric(length(s))
>        for(shift in (0:3)*16) {
>            # nibble <- as.integer(as.hexmode(substring(s, n-3, n)))
>            nibble <- as.integer(sapply(substring(s, n-3, n), as.hexmode))
>            n <- n - 4
>            acc <- acc + 2^shift * nibble
>        }
>        acc
>    }
>    retval[["startAddr"]] <- hex64StringToDouble(retval[["startAddr"]])
>    retval[["endAddr"]] <- hex64StringToDouble(retval[["endAddr"]])
>    retval
> }
> 
> Bill Dunlap
> Spotfire, TIBCO Software
> wdunlap tibco.com
> 
> 
>> -----Original Message-----
>> From: r-devel-bounces at r-project.org [mailto:r-devel-bounces at r-project.org] On Behalf
>> Of Rory Winston
>> Sent: Thursday, June 13, 2013 3:56 AM
>> To: r-devel at r-project.org
>> Subject: Re: [Rd] load/unload segfault puzzle
>> 
>> Ben
>> 
>> Have you compiled R form source yourself? If so, I would be tempted to mark up
>> memory. c with some debug log statements - especially around line 1357, and possibly
>> inside the finalizers function as it attempts to run the C finalizers....not pretty I know, but
>> may be the quickest approach to quickly identify whats failing...
>> Cheers
>> -- Rory
>> 
>> 
>> 
>>> Yes, thanks -- Bill Dunlap already suggested this.  Your and Bill's
>>> warning about how slow gctorture makes things is correct -- I gave up
>>> after running for 3.5 hours when it had gotten only partway through
>>> loading the Matrix package; I will have to find a machine with a decent
>>> cooling system (i.e. not my laptop) where I can replicate the error.
>>> I've just re-run the regular valgrind, with a fresh build right after
>>> an SVN update.  I got exactly the same results as above.  We're
>>> certainly *not* calling reg.finalizer() anywhere in our package, and I
>>> don't think Rcpp or RcppEigen or minqa do ... there looks to be some
>>> kind of default finalization done on the reference class objects (based
>>> on running 'strings' on the object files ...
>>> I tried gdb'ing in and setting a breakpoint at memory.c:1357, but this
>>> breakpoint gets hit a lot, and I'm sort of stabbing in the dark at this
>>> point.
>>> 
>>>  Ben Bolker
>>> 
>>> 
>>> 
>>> ------------------------------
>>> 
>>> _______________________________________________
>>> R-devel at r-project.org mailing list  DIGESTED
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>> 
>>> 
>>> End of R-devel Digest, Vol 124, Issue 12
>>> ****************************************
>> 
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list