代码之家  ›  专栏  ›  技术社区  ›  Janina

捕获到segfault-“内存未映射”错误,在R中

  •  29
  • Janina  · 技术社区  · 7 年前

    我在集群上运行一些R脚本时遇到问题。问题突然出现了(所有的脚本都运行得很好,但有一天他们开始给出 caught segfault 错误)。我无法提供可复制的代码,因为我甚至无法在自己的计算机上复制错误-它只发生在集群上。我还对两组数据使用了相同的代码—一组非常小,运行良好,另一组处理更大的数据帧(约1000万行),并在某些点折叠。我只使用来自CRAN存储库的包;R和所有包都应是最新的。错误出现在完全不相关的操作中,请参见以下示例:

    会话信息:

    R version 3.4.3 (2017-11-30)
    Platform: x86_64-redhat-linux-gnu (64-bit)
    Running under: CentOS Linux 7 (Core)
    

    将变量写入NetCDF文件

    # code snippet
    library(ncdf4)
    library(reshape2)
    
    input <- read.csv("input_file.csv")
    species <- "no2"
    dimX <- ncdim_def(name="x", units = "m", vals = unique(input$x), unlim = FALSE)
    dimY <- ncdim_def(name="y", units = "m", vals = unique(input$y), unlim = FALSE)
    dimTime <- ncdim_def(name = "time", units = "hours", unlim = TRUE)
    
    varOutput <- ncvar_def(name = species, units = "ug/m3",
                    dim = list(dimX, dimY, dimTime), missval = -9999, longname = species)
    
    nc_file <- nc_create(filename = "outFile.nc", vars = list(varOutput), force_v4 = T)
    
    ncvar_put(nc = nc_file, varid = species, vals = acast(input, x~y), start = c(1,1,1),
          count = c(length(unique(input$x)), length(unique(input$y)), 1))
    

    此时,我得到以下错误:

     *** caught segfault ***
    address 0x2b607cac2000, cause 'memory not mapped'
    
    Traceback:
     1: id(rev(ids), drop = FALSE)
     2: cast(data, formula, fun.aggregate, ..., subset = subset, fill = fill,     drop = drop, value.var = value.var)
     3: acast(result, x ~ y)
     4: ncvar_put(nc = nc_file, varid = species, vals = acast(result, x ~     y), start = c(1, 1), count = c(length(unique(result$x)),     length(unique(result$y))))
    An irrecoverable exception occurred. R is aborting now ...
    /opt/sge/default/spool/node10/job_scripts/122270: line 3: 13959 Segmentation fault      (core dumped)
    

    具有并行计算的复杂代码

     *** caught segfault ***
    address 0x330d39b40, cause 'memory not mapped'
    
    Traceback:
     1: .Call(gstat_fit_variogram, as.integer(fit.method), as.integer(fit.sills),     as.integer(fit.ranges))
     2: fit.variogram(experimental_variogram, model = vgm(psill = psill,     model = model, range = range, nugget = nugget, kappa = kappa),     fit.ranges = c(fit_range), fit.sills = c(fit_nugget, fit_sill),     debug.level = 0)
     3: doTryCatch(return(expr), name, parentenv, handler)
     4: tryCatchOne(expr, names, parentenv, handlers[[1L]])
     5: tryCatchList(expr, classes, parentenv, handlers)
     6: 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]]        w <- 14L + nchar(dcall, type = "w") + nchar(sm[1L], type = "w")        if (is.na(w))             w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L],                 type = "b")        if (w > LONG)             prefix <- paste0(prefix, "\n  ")    }    else prefix <- "Error : "    msg <- paste0(prefix, conditionMessage(e), "\n")    .Internal(seterrmessage(msg[1L]))    if (!silent && identical(getOption("show.error.messages"),         TRUE)) {        cat(msg, file = outFile)        .Internal(printDeferredWarnings())    }    invisible(structure(msg, class = "try-error", condition = e))})
     7: try(fit.variogram(experimental_variogram, model = vgm(psill = psill,     model = model, range = range, nugget = nugget, kappa = kappa),     fit.ranges = c(fit_range), fit.sills = c(fit_nugget, fit_sill),     debug.level = 0), TRUE)
     8: getModel(initial_sill - initial_nugget, m, initial_range, k,     initial_nugget, fit_range, fit_sill, fit_nugget, verbose = verbose)
     9: autofitVariogram(lmResids ~ 1, obsDf, model = "Mat", kappa = c(0.05,     seq(0.2, 2, 0.1), 3, 5, 10, 15), fix.values = c(NA, NA, NA),     start_vals = c(NA, NA, NA), verbose = F)
    10: main_us(obsDf[obsDf$class == "rural" | obsDf$class == "rural-nearcity" |     obsDf$class == "rural-regional" | obsDf$class == "rural-remote",     ], grd_alt, grd_pop, lm_us, fitvar_us, logTransform, plots,     "RuralSt", period, preds)
    11: doTryCatch(return(expr), name, parentenv, handler)
    12: tryCatchOne(expr, names, parentenv, handlers[[1L]])
    13: tryCatchList(expr, classes, parentenv, handlers)
    14: tryCatch(main_us(obsDf[obsDf$class == "rural" | obsDf$class ==     "rural-nearcity" | obsDf$class == "rural-regional" | obsDf$class ==     "rural-remote", ], grd_alt, grd_pop, lm_us, fitvar_us, logTransform,     plots, "RuralSt", period, preds), error = function(e) e)
    15: eval(.doSnowGlobals$expr, envir = .doSnowGlobals$exportenv)
    16: eval(.doSnowGlobals$expr, envir = .doSnowGlobals$exportenv)
    17: doTryCatch(return(expr), name, parentenv, handler)
    18: tryCatchOne(expr, names, parentenv, handlers[[1L]])
    19: tryCatchList(expr, classes, parentenv, handlers)
    20: tryCatch(eval(.doSnowGlobals$expr, envir = .doSnowGlobals$exportenv),     error = function(e) e)
    21: (function (args) {    lapply(names(args), function(n) assign(n, args[[n]], pos = .doSnowGlobals$exportenv))    tryCatch(eval(.doSnowGlobals$expr, envir = .doSnowGlobals$exportenv),         error = function(e) e)})(quote(list(timeIndex = 255L)))
    22: do.call(msg$data$fun, msg$data$args, quote = TRUE)
    23: doTryCatch(return(expr), name, parentenv, handler)
    24: tryCatchOne(expr, names, parentenv, handlers[[1L]])
    25: tryCatchList(expr, classes, parentenv, handlers)
    26: tryCatch(do.call(msg$data$fun, msg$data$args, quote = TRUE),     error = handler)
    27: doTryCatch(return(expr), name, parentenv, handler)
    28: tryCatchOne(expr, names, parentenv, handlers[[1L]])
    29: tryCatchList(expr, classes, parentenv, handlers)
    30: tryCatch({    msg <- recvData(master)    if (msg$type == "DONE") {        closeNode(master)        break    }    else if (msg$type == "EXEC") {        success <- TRUE        handler <- function(e) {            success <<- FALSE            structure(conditionMessage(e), class = c("snow-try-error",                 "try-error"))        }        t1 <- proc.time()        value <- tryCatch(do.call(msg$data$fun, msg$data$args,             quote = TRUE), error = handler)        t2 <- proc.time()        value <- list(type = "VALUE", value = value, success = success,             time = t2 - t1, tag = msg$data$tag)        msg <- NULL        sendData(master, value)        value <- NULL    }}, interrupt = function(e) NULL)
    31: slaveLoop(makeSOCKmaster(master, port, timeout, useXDR))
    32: parallel:::.slaveRSOCK()
    An irrecoverable exception occurred. R is aborting now ...
    

    是否可能是集群而不是代码(或R)存在问题?我不知道这是否有关联,但从一段时间前开始,我们收到了如下错误消息:

    Message from syslogd@master1 at Mar  8 13:51:37 ...
     kernel:[Hardware Error]: MC4 Error (node 1): DRAM ECC error detected on the NB.
    
    Message from syslogd@master1 at Mar  8 13:51:37 ...
     kernel:[Hardware Error]: Error Status: Corrected error, no action required.
    
    Message from syslogd@master1 at Mar  8 13:51:37 ...
     kernel:[Hardware Error]: CPU:4 (15:2:0) MC4_STATUS[-|CE|MiscV|-|AddrV|-|-|CECC]: 0x9c08400067080a13
    
    Message from syslogd@master1 at Mar  8 13:51:37 ...
    kernel:[Hardware Error]: MC4_ADDR: 0x000000048f32b490
    
    Message from syslogd@master1 at Mar  8 13:51:37 ...
     kernel:[Hardware Error]: cache level: L3/GEN, mem/io: MEM, mem-tx: RD, part-proc: RES (no timeout)
    

    我已尝试基于卸载和重新安装软件包 this question 但这没有帮助。

    5 回复  |  直到 7 年前
        1
  •  14
  •   pauljohn32    7 年前

    问题是当前安装的共享库与为安装R或包而构建的库之间不匹配。

    今天我第一次遇到这个错误。见下文。我已经解决了,可以解释情况了。

    这是一个Ubuntu系统,最近从17.10升级到18.04,运行R-3.4.4。许多C和C++库被替换。但并非所有程序都被替换。我立刻注意到许多程序都出现了分段错误。任何触碰到tidyverse的东西都是失败的。这个 stringi 包找不到用于编译它的共享库。

    这里的示例有点有趣,因为它发生在对包运行“R CMD check”时,至少在理论上应该是安全的。我发现修复方法是删除包“RCurl”和“url”并重建它们。

    不管怎样,症状是这样的

    * checking for file ‘kutils.gitex/DESCRIPTION’ ... OK
    * preparing ‘kutils’:
    * checking DESCRIPTION meta-information ... OK
    * installing the package to build vignettes
    * creating vignettes ... OK
    * checking for LF line-endings in source and make files and shell scripts
    * checking for empty or unneeded directories
    * looking to see if a ‘data/datalist’ file should be added
    * re-saving image files
    * building ‘kutils_1.40.tar.gz’
    Warning: invalid uid value replaced by that for user 'nobody'
    Warning: invalid gid value replaced by that for user 'nobody'
    
    Run check: OK? (y or n)y
    * using log directory ‘/home/pauljohn/GIT/CRMDA/software/kutils/package/kutils.Rcheck’
    * using R version 3.4.4 (2018-03-15)
    * using platform: x86_64-pc-linux-gnu (64-bit)
    * using session charset: UTF-8
    * using option ‘--as-cran’
    * checking for file ‘kutils/DESCRIPTION’ ... OK
    * checking extension type ... Package
    * this is package ‘kutils’ version ‘1.40’
    * checking CRAN incoming feasibility ...
     *** caught segfault ***
    address 0x68456, cause 'memory not mapped'
    
    Traceback:
     1: curlGetHeaders(u)
     2: doTryCatch(return(expr), name, parentenv, handler)
     3: tryCatchOne(expr, names, parentenv, handlers[[1L]])
     4: tryCatchList(expr, classes, parentenv, handlers)
     5: tryCatch(curlGetHeaders(u), error = identity)
     6: .fetch(u)
     7: .check_http_A(u)
     8: FUN(X[[i]], ...)
     9: lapply(urls[pos], .check_http)
    10: do.call(rbind, lapply(urls[pos], .check_http))
    11: check_url_db(url_db_from_package_sources(dir), remote = !localOnly)
    12: doTryCatch(return(expr), name, parentenv, handler)
    13: tryCatchOne(expr, names, parentenv, handlers[[1L]])
    14: tryCatchList(expr, classes, parentenv, handlers)
    15: tryCatch(check_url_db(url_db_from_package_sources(dir), remote = !localOnly),     error = identity)
    16: .check_package_CRAN_incoming(pkgdir, localOnly)
    17: check_CRAN_incoming(!check_incoming_remote)
    18: tools:::.check_packages()
    An irrecoverable exception occurred. R is aborting now ...
    Segmentation fault
    
        2
  •  7
  •   Janina    7 年前

    这并不是对问题的真正解释或令人满意的答案,但我更仔细地检查了代码,发现在第一个示例中,当使用 acast reshape2 包裹在这种情况下,我删除了它,因为我意识到它实际上不需要,但可以替换为 reshape 重塑形状 包装(如所示 another question ): reshape(input, idvar="x", timevar="y", direction="wide")[-1]

    至于第二个例子,要找到问题的确切原因并不容易,但在我的例子中,作为一种解决方法,可以帮助设置较少数量的用于并行计算的内核-集群有48个,我只使用了15个,因为即使在这个问题之前,如果代码使用全部48个内核运行,R的内存也会不足。当我将核心数减少到10个时,它突然像以前一样开始工作。

        3
  •  1
  •   passerby51    3 年前

    为了增加@pauljohn32的响应,如果您使用 sourceRcpp 要获得C++代码,请执行以下操作 A.cpp 比如说,这依赖于C++代码 B.cpp C.cpp ,它是根据一个旧的/不同的库编译的。

    在Linux中,一个简单的解决方案是删除 B.o C.o 运行前的文件 sourceRcpp("A.cpp") 。这似乎也会自动重新编译从属文件,前提是您在 A、 cpp公司


    关于Matt Nolan的回答,请编辑更多详细信息:关于最初的问题,问题很可能与此类似,因为共享库是为较旧版本的操作系统或其他系统编译的。我在这里要说的是,即使您自己编写和编译了整个项目,如果您忘记清理过时的文件,也可能发生这种情况。

    给一个与问题相关的类比: 深入了解的源代码 ncdf4 问题中引用的包,我们在 src\ncdf.c

    #include <stdio.h>
    #include <netcdf.h>
    #include <string.h>
    #include <stdlib.h>
    
    #include <Rdefines.h>
    #include <R_ext/Rdynload.h>
    

    比如说文件 R_ext/Rdynload.h microsof-r-open 项目这是一个头文件和相应的 Rdynload.c 可以找到 here

    认为 ncdf4 microsof-r-open 都是单个项目的一部分,并且您已在 open/blob/master/source/src/main 已经生成了对象文件 Rdynload.o 除其他外,还有。然后,在编译之前 src\ncdf。c ,您可以升级操作系统(不确定这是否一定会导致问题),或者将整个源代码(包括迄今为止创建的目标文件)复制到另一台计算机。这可能会在无意中发生。

    例如,您有 自动同步 继续,目录与另一台计算机同步。在这台不同的机器上,然后尝试编译和链接 src\ncdf。c 。编译器/链接器不重新编译 Rdynload。c 自对象文件 Rdynload。o 已经存在了。它符合 src\ncdf。c 生产 src\ncdf.o 然后将其链接到 Rdynload。o 构建最终可执行文件。

    我不是这里的专家,但也许 Rdynload 是一个动态链接库,链接正常,没有错误。但在运行时,由于编译库的目标代码之间的版本不匹配,会出现分段错误 Rdynload公司 和目标代码 ncdf (?)。对于低级机器执行有更好了解的人可以在这里纠正我。

    解决方案是清除所有对象文件,即具有扩展名的文件 *.o 并让编译器从头开始重新编译所有内容。这个 *。o 扩展假定您在Linux机器上。其他操作系统可能使用不同的扩展。

    对于您不拥有的项目,解决方案可能是重新安装相关的库(假设它们没有预编译,并且在安装时在新机器上重新编译)。

        4
  •  0
  •   haff    3 年前

    对我来说,问题是报价类型存在差异。我有一个 ” 当R想要 " 。解决此问题。

        5
  •  -3
  •   ecp    7 年前

    强烈建议清理工作区,这可能是核心问题:

    unlink(".RData")