Skip to content

How to detach binary objects/libraries?

6 messages · Peter Dimitrov, Brian Ripley, Peter Dalgaard

#
Hi all,

First, I want to apologize if this question has been already answered. I
have a RedHat 7.2. system with recently patched version of R-1.4.1. I'm
in a process of writing R package, say X, that loads some C++ code.
Currently, while adding functionality to it in both R and C++ sources,
I'm getting crashes every time I detach/load/access the C++ function(s).
Typical transcript follows:
Loading required package: mva
[1] TRUE
[1] TRUE # Problem?
Process R:1 segmentation fault at Mon Mar 25 12:17:57 2002

What is the way to cleanly unload the object code and is there better
mechanism than detach(package:X)?

Thanks,

Peter Dimitrov

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
On 25 Mar 2002, Peter Dimitrov wrote:

            
Does you package use .Last.lib to unload your shared library, X.so?
If not, that will probably be your problem, as library.dynam will not
reload it (and you probably use library.dynam).

Take a look at package tcltk for an example.

I'm not sure what Linux does if you change a shared library that is in
use, but it is not a good idea (and fatal on Solaris, for example).
#
On Mon, 2002-03-25 at 13:46, ripley at stats.ox.ac.uk wrote:
Thank you, Prof. Ripley!

Adding .Last.lib solved the segmentantion fault problem. On the other
hand, it created the following puzzle. Transcript follows:
Loading required package: mva
[1] TRUE
[1] FALSE
[1] FALSE
Error in .C("exp_dist_fast", ...),  : 
	C/Fortran function name not in load table
Error in dyn.unload(x) : dynamic/shared library
"/opt/lib/R/library/X/libs/X.so" was not loaded

X's zzz.R follows:

.First.lib <- function( lib, pkg )
  library.dynam( "X", pkg, lib )

.Last.lib <- function( libpath )
  dyn.unload(
             file.path( libpath,
                       "libs",
                       paste( "X", .Platform$"dynlib.ext", sep = "" )
                       )
             )

Is the solution just to change library.dynam with dyn.load( file.path(
..))?
It's probably quite wrong, but I was hoping that it will work much the
same way as in sourcing the original not-yet-in-a-package R file that
dynamically loads X.so. In Linux it reloads X.so without a problem.
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
On 25 Mar 2002, Peter Dimitrov wrote:

            
No, it is to follow the example I pointed you too.  You need code like

.Last.lib <- function(libpath) {
    if(is.loaded(symbol.C("tcltk_end"))) {
        .C("tcltk_end", PACKAGE="tcltk")
        dyn.unload(file.path(libpath, "libs", "tcltk.dll"))
        num <- match("tcltk", get(".Dyn.libs", envir = NULL))
        assign(".Dyn.libs",
               get(".Dyn.libs", envir = NULL)[-num],
               envir = NULL)
    }
}
But my point was: what does changing the file copy of an already loaded
shared library do?   It's not allowed on Windows, and on Solaris it will
lead to a crash.  I don't know about Linux, as I would never try it
given my experience.
#
Prof Brian D Ripley <ripley at stats.ox.ac.uk> writes:
AFAIR, it works on Linux. Running processes just continue using the
old version (which gets unlinked in the usual Unix way and goes away
when no more processes are using it). E.g., you can upgrade the
readline library without crashing all running instances of bash...

On Solaris, I believe that overwriting a shared lib will write
directly into the memory space of any process using the file.
#
On 26 Mar 2002, Peter Dalgaard BSA wrote:

            
bash is using a static readline.  E.g. RH7.2:

gannet% ldd /bin/bash
        libtermcap.so.2 => /lib/libtermcap.so.2 (0x4002e000)
        libdl.so.2 => /lib/libdl.so.2 (0x40032000)
        libc.so.6 => /lib/i686/libc.so.6 (0x40036000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

More importantly it's not the same issue.  That would have been linking
against a shared library which the OS loads, and R is itself loading a
module which happens to be a shared library.  On MacOS X those are
different concepts.  As I understand it Linux's ld.so is not able to
update in-use shared libraries: it relies on a change in version number.