我在群集上运行某些 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)
我尝试根据此问题卸载并重新安装软件包,但没有帮助。
问题是当前安装的共享库与为安装 R 或包而构建的库不匹配。
我今天第一次收到此错误。见下文。我已经解决了,可以解释情况。
这是一个最近从 17.10 升级到 18.04 的 Ubuntu 系统,运行 R-3.4.4。许多 C 和 C++ 库被替换。但并非所有程序都被替换。 我立即注意到许多程序都出现了分段错误。 任何触及整洁的东西都是失败的。stringi
包找不到用于编译它的共享库。
这里的例子有点有趣,因为它发生在对包运行"R CMD 检查"时,至少在理论上应该是安全的。 我发现解决方法是删除包"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
这不是对问题的解释或令人满意的答案,但我更仔细地检查了代码,并发现在第一个例子中,使用reshape2
包中的acast
时会出现问题。在这种情况下,我删除了它,因为我意识到那里实际上并不需要它,但它可以用reshape
包中的reshape
替换(如另一个问题所示):reshape(input, idvar="x", timevar="y", direction="wide")[-1]
.
至于第二个示例,要找到问题的确切原因并不容易,但作为我案例中的解决方法,帮助设置了用于并行计算的较少数量的内核 - 集群有 48 个,我只使用了 15 个,因为即使在这个问题之前,如果代码使用所有 48 个内核运行,R 内存不足。当我将内核数量减少到 10 个时,它突然开始像以前一样工作。
为了添加到@pauljohn32的响应中,如果您使用sourceRcpp
来获取依赖于C++代码(例如B.cpp
和C.cpp
)的C++代码(例如A.cpp
),也会发生这种情况,该代码是针对较旧/不同的库编译的。
在Linux中,一个简单的解决方案是在运行sourceRcpp("A.cpp")
之前删除B.o
和C.o
文件。这似乎也会自动重新编译依赖文件,假设您在A.cpp
中包含标头。
举一个与问题相关的类比: 深入研究问题中引用ncdf4
包的源代码,我们在srcncdf.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
可以在这里找到。
假设ncdf4
和microsof-r-open
都是单个项目的一部分,并且您已经在open/blob/master/source/src/main
中编译了文件,这将生成目标文件Rdynload.o
那里等。然后,在编译srcncdf.c
之前,您升级操作系统(不确定这是否必然会导致问题)或将整个源代码(包括到目前为止创建的目标文件)复制到另一台计算机上。 这可能会无意中发生。
例如,您正在进行自动同步,并且目录与其他计算机同步。在这台不同的机器上,您尝试编译并链接srcncdf.c
。编译器/链接器不会重新编译Rdynload.c
因为目标文件Rdynload.o
已经存在。它符合生成srcncdf.o
的srcncdf.c
,然后将其与Rdynload.o
链接以构建最终的可执行文件。
我不是这里的专家,但由于也许Rdynload
是一个动态链接的库,因此链接正常,没有错误。但在运行时,由于符合库Rdynload
的目标代码与目标代码ncdf
(?) 之间的版本不匹配,您会收到分段错误。对低级机器执行有更好了解的人可以在这里纠正我。
解决方案是清除所有目标文件,即所有源目录中扩展名为*.o
的文件,并让编译器从头开始重新编译所有内容。*.o
扩展假定您使用的是 Linux 计算机。其他操作系统可能使用不同的扩展名。
对于您不拥有的项目,也许解决方案是重新安装相关库(假设它们没有预编译并在安装时在新机器上重新编译)。
对我来说,问题是报价类型的差异。当R想要"
时,我有一个”
。修复此问题解决了问题。
强烈建议清洁工作区,可能是核心问题:
unlink(".RData")