From nikelski at bic.mni.mcgill.ca  Fri Aug 14 00:41:10 2009
From: nikelski at bic.mni.mcgill.ca (EJ Nikelski)
Date: Thu, 13 Aug 2009 18:41:10 -0400
Subject: [Rd] segfault when unloading a shared library
In-Reply-To: <4A846D19.4080907@fhcrc.org>
References: <e12172550908131227n14988da4r2efcd62d59b8da76@mail.gmail.com>
	<4A846D19.4080907@fhcrc.org>
Message-ID: <e12172550908131541r16e20514n4a4b75d1b95de2f2@mail.gmail.com>

Dear List,

   Martin, thanks for the extremely useful advice.  As valgrind is not
yet officially available for OS X, I grabbed the 3.5.0 beta from svn,
built it, and gave it a go.  The results were enlightening:

-------------------------------------------------
> # unload the library for updating
> detach(package:mniMincIO)
Unloading shared library: mniMincIO. Library unload path is
/Users/jnikelski/R_libs/2.9/mniMincIO
now dyn.unload("/Users/jnikelski/R_libs/2.9/mniMincIO/libs/i386/mniMincIO.so")
...
Unloading shared library mniMincIO in R_unload_mniMincIO
==3254== Jump to the invalid address stated on the next line
==3254==    at 0x80765E0: ???
==3254==    by 0x8090430: H5_term_library (in
/usr/local/bic/2009.08.10/lib/libhdf5.0.0.0.dylib)
==3254==    by 0x653DC6: __cxa_finalize (in /usr/lib/libSystem.B.dylib)
==3254==    by 0x68983E: dwarf2_unwind_dyld_remove_image_hook (in
/usr/lib/libSystem.B.dylib)
==3254==    by 0x8FE030D4: dyld::removeImage(ImageLoader*) (in /usr/lib/dyld)
==3254==    by 0x8FE031FD: dyld::garbageCollectImages() (in /usr/lib/dyld)
==3254==    by 0x8FE0BE05: dlclose (in /usr/lib/dyld)
==3254==    by 0x685E31: dlclose (in /usr/lib/libSystem.B.dylib)
==3254==    by 0x31ACDC: DeleteDLL (in
/Library/Frameworks/R.framework/Versions/2.9/Resources/lib/libR.dylib)
==3254==    by 0x31BA95: do_dynunload (in
/Library/Frameworks/R.framework/Versions/2.9/Resources/lib/libR.dylib)
==3254==    by 0x3F267E: do_internal (in
/Library/Frameworks/R.framework/Versions/2.9/Resources/lib/libR.dylib)
==3254==    by 0x3B7337: Rf_eval (in
/Library/Frameworks/R.framework/Versions/2.9/Resources/lib/libR.dylib)
==3254==  Address 0x80765e0 is not stack'd, malloc'd or (recently) free'd
==3254==

 *** caught segfault ***
address 0x0, cause 'memory not mapped'
--------------------------------------

   It would appear that during certain read/write operations, the HDF
lib registers its own clean up call via an atexit() routine.  The
unload of the upstream library (mniMincIO, in this case) appears to
trigger the atexit() HDF routine ... however, the HDF library is
already unloaded ... causing a jump into oblivion.

   There are 2 possible solutions that are immediately obvious to me:
(1) use the H5dont_atexit() function to prevent the registering of the
cleanup function, and/or (2) find some way of forcing the HDF library
not to unload.  I would prefer (2), but am not sophisticated enough to
figure out the best way to do this.  Any Mac experts following this
thread?  Simon?

Cheers,

-Jim


On Thu, Aug 13, 2009 at 3:44 PM, Martin Morgan<mtmorgan at fhcrc.org> wrote:
> R -d valgrind -f 'simple_script.R' can be very helpful for this.
>
> Martin
>
> EJ Nikelski wrote:
>> Hi All,
>>
>> ? ?I'm still actively researching this problem (reading R-ext manual),
>> but I hoped that I might be able to get some additional insight from
>> the list given that I'm fairly new at writing R extension code.
>>
>> ?Problem: ?I have some fairly simple code (.Call interface) that makes
>> a call to another shared library, which, in turn, calls routines in an
>> HDF5 shared library. ?The good news is that everything works (the
>> expected value is returned from the HDF5 call); the problem is that R
>> segfaults when I unload the library.
>>
>> ? I initially suspected that the HDF5 function might be corrupting the
>> stack/heap, however, if it is, it's not obvious to me. ?Upon the
>> successful return from the function, R responds well, and a gc() call
>> works without event (only when unloading do I see the problem). In
>> addition, given that the function returns a ?single (double) value, I
>> passed a much larger array in order to see whether the HDF routine
>> might be writing off the end of the buffer; the pre-initialized buffer
>> looked OK upon return. ?Interestingly, when I comment out the call to
>> the HDF routine and manually return a double value, the problem
>> disappears. So, something within that particular HDF function (other
>> HDF functions work OK) is messing something up, which is only apparent
>> at unload time. ?Any idea where I should be looking?
>>
>> The abort output and environment details follow (I don't seem to get a
>> core dump). Please let me know if any other information might be
>> helpful, and what I might try next.
>>
>> Thanks,
>>
>> -Jim
>>
>>
>> ---------------------------------------------------
>>> detach(package:mniMincIO)
>> Unloading shared library: mniMincIO. Library unload path is
>> /Users/jnikelski/R_libs/2.9/mniMincIO
>> now dyn.unload("/Users/jnikelski/R_libs/2.9/mniMincIO/libs/i386/mniMincIO.so")
>> ...
>> Unloading shared library mniMincIO in R_unload_mniMincIO
>>
>> ?*** caught segfault ***
>> address 0xcfa5e0, cause 'memory not mapped'
>>
>> Traceback:
>> ?1: dyn.unload(file)
>> ?2: library.dynam.unload(libName, file.ext = ".so", verbose = TRUE,
>> ?libpath = libpath)
>> ?3: .Last.lib(libpath)
>> ?4: doTryCatch(return(expr), name, parentenv, handler)
>> ?5: tryCatchOne(expr, names, parentenv, handlers[[1L]])
>> ?6: tryCatchList(expr, classes, parentenv, handlers)
>> ?7: tryCatch(expr, error = function(e) { ? ?call <- conditionCall(e)
>> ?if (!is.null(call)) { ? ? ? ?if (identical(call[[1L]],
>> quote(doTryCatch))) ? ? ? ? ? ? call <- sys.call(-4L) ? ? ? ?dcall <-
>> deparse(call)[1L] ? ? ? ?prefix <- paste("Error in", dcall, ": ")
>> ?LONG <- 75L ? ? ? ?msg <- conditionMessage(e) ? ? ? ?sm <-
>> strsplit(msg, "\n")[[1L]] ? ? ? ?if (14L + nchar(dcall, type = "w") +
>> nchar(sm[1L], type = "w") > ? ? ? ? ? ? LONG) ? ? ? ? ? ? prefix <-
>> paste(prefix, "\n ?", sep = "") ? ?} ? ?else prefix <- "Error : "
>> msg <- paste(prefix, conditionMessage(e), "\n", sep = "")
>> .Internal(seterrmessage(msg[1L])) ? ?if (!silent &&
>> identical(getOption("show.error.messages"), ? ? ? ? TRUE)) {
>> cat(msg, file = stderr()) ? ? ? ?.Internal(printDeferredWarnings())
>> } ? ?invisible(structure(msg, class = "try-error"))})
>> ?8: try(.Last.lib(libpath))
>> ?9: detach(package:mniMincIO)
>>
>> Possible actions:
>> 1: abort (with core dump, if enabled)
>> 2: normal R exit
>> 3: exit R without saving workspace
>> 4: exit R saving workspace
>> Selection: 1
>> aborting ...
>> Segmentation fault
>>
>>> sessionInfo()
>> R version 2.9.1 (2009-06-26)
>> i386-apple-darwin8.11.1
>>
>> locale:
>> en_CA.UTF-8/en_CA.UTF-8/C/C/en_CA.UTF-8/en_CA.UTF-8
>>
>> attached base packages:
>> [1] stats ? ? graphics ?grDevices utils ? ? datasets ?methods ? base
>>
>> -----------------------------------------------------------------
>>
>>
>>
>> --
>> =================================
>> Jim Nikelski, Ph.D.
>> Postdoctoral Research Fellow
>> Bloomfield Centre for Research in Aging
>> Lady Davis Institute for Medical Research
>> Sir Mortimer B. Davis - Jewish General Hospital
>> McGill University
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>



-- 
=================================
Jim Nikelski, Ph.D.
Postdoctoral Research Fellow
Bloomfield Centre for Research in Aging
Lady Davis Institute for Medical Research
Sir Mortimer B. Davis - Jewish General Hospital
McGill University



[Rd] segfault when unloading a shared library
EJ Nikelski