From wdunlap at tibco.com  Thu Jun 13 16:34:29 2013
From: wdunlap at tibco.com (William Dunlap)
Date: Thu, 13 Jun 2013 14:34:29 +0000
Subject: [Rd] load/unload segfault puzzle
In-Reply-To: <7353B511-62FF-4FEA-AA9D-8BFBBD4F985D@gmail.com>
References: <mailman.35.1371117609.3499.r-devel@r-project.org>
	<7353B511-62FF-4FEA-AA9D-8BFBBD4F985D@gmail.com>
Message-ID: <E66794E69CFDE04D9A70842786030B931C30295F@PA-MBX01.na.tibco.com>

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



[Rd] load/unload segfault puzzle
William Dunlap