valgrind 快速_valgrind memcheck与RA快速,肮脏的指南

valgrind 快速

This may or may not help someone. It is a quick and dirty guide written by a first time valgrind memcheck user. I wished for something similar, so here it is.

这可能会或可能不会帮助某人。 这是由valgrind的首次memcheck用户编写的快速而肮脏的指南。 我希望有类似的东西,所以就在这里。

Suppose, like me, you submit your new R package, version 1.0.0, to CRAN and it’s accepted. You rejoice happily and move on to bigger things, like building a fantastic update. After a few months you have 8000 downloads, your cool new update is done, and you submit version 1.0.1. Being the amazing professional that you are, you expect your work will slide breezily through into CRAN.

假设像我一样,您将新的R软件包 1.0.0版提交给CRAN,它被接受了。 您会高兴地开心,然后继续进行更大的事情,例如构建出色的更新。 几个月后,您下载了8000次,完成了很酷的新更新,然后提交了版本1.0.1。 作为一名出色的专业人士,您希望您的工作会轻松地进入CRAN。

You get an email from CRAN saying everything is great, except for one little issue: there were some errors detected in your previous version (1.0.0) during some kind of secondary checking procedure, reported by this thing called valgrind, which apparently detects “memory management and threading bugs”, but you have no idea what that is. Your spirits are still high. You’re sure this is no big deal…

您从CRAN收到一封电子邮件,其中说的一切都很好,除了一个小问题:在先前版本 (1.0.0)中检测到一些错误 某种辅助检查过程期间,报道这个东西叫做Valgrind的 这显然检测“ 内存管理和线程错误 ”,但你不知道那是什么。 你的情绪仍然很高。 您确定这没什么大不了的...

I hope that this quick guide, from my similar experience, can alleviate some of the pain that may be to come. That way, you can get your R package on CRAN and spend the weekend doing the things you love, like reading stats journals.

我希望从我的类似经验中获得这份快速指南,可以减轻可能出现的一些痛苦。 这样,您就可以在CRAN上获得R包,并度过一个周末来做自己喜欢的事情,例如阅读统计期刊。

Step 0: Get Linux (skip if you have Linux).

步骤0:获取Linux(如果有Linux,请跳过)。

It’s time to get Linux, if you don’t already have it. It really makes life easier. Besides, I have no idea how to do this without Linux. For a newbie, Linux Mint is the best distribution (in my humble opinion).

如果您还没有Linux,那么该是时候得到它了。 这确实使生活更轻松。 此外,我不知道没有Linux怎么做。 对于新手来说,Linux Mint是最好的发行版(以我的拙见)。

Note: You may run into a number of errors to do with package dependencies if you’re using a fresh installation of Linux. The easiest solution is to wait until you get an error and then copy some part of the error into a search engine and find a forum where someone has outlined what dependencies you need to install.

注意:如果您使用的是全新安装的Linux,则可能会遇到许多与软件包依赖项有关的错误。 最简单的解决方案是等到收到错误后,再将错误的一部分复制到搜索引擎中,然后找到一个论坛,其中有人概述了您需要安装的依赖项。

Note: I suggest using git to copy your package files from your remote repository (e.g., a GitHub repo) to your Linux machine.

注意:我建议使用git将软件包文件从远程存储库(例如GitHub存储库)复制到Linux计算机。

Step 1: Install valgrind.

步骤1:安装valgrind。

Something like this should work

这样的事情应该工作

sudo apt-get install valgrind

Step 2: Run R CMD Check.

步骤2:执行R CMD检查。

You need to specify the directory “./check” with check_dir so that you can retrieve mypkg-Ex.R from the results.

您需要使用check_dir指定目录“./check” ,以便可以从结果中检索mypkg-Ex.R

rcmdcheck::rcmdcheck( check_dir = ”./check” )

Step 3: Run valgrind on R CMD Check examples.

步骤3:在R CMD Check示例上运行valgrind。

Open your terminal in the package directory. In Ubuntu you can do this as follows: open the package directory in the file explorer, press CTRL-L to highlight the address bar, followed by CTRL+C to copy the address, then open terminal and type cd followed by a space, then press CTRL+SHIFT+V to paste the address. Now, run (replacing mypkg with the name of your package):

在包目录中打开您的终端。 在Ubuntu中,您可以执行以下操作:在文件资源管理器中打开包目录,按CTRL-L突出显示地址栏,然后按CTRL+C复制地址,然后打开终端并键入cd,后跟一个空格,然后按CTRL+SHIFT+V粘贴地址。 现在,运行(用包名替换mypkg ):

R -d valgrind --vanilla < “./check/mypkg.Rcheck/mypkg-Ex.R”

The script mypkg-Ex.R will be executed with valgrind running in the background. Valgrind is looking for memory issues. It will run through all the examples in mypkg-Ex.R and every time valgrind detects an issue it will print some (helpful?) information, such as:

脚本mypkg-Ex.R将在后台运行valgrind的情况下执行。 Valgrind正在寻找内存问题。 它将遍历mypkg-Ex.R所有示例,并且每当valgrind检测到问题时,它将打印一些(有用的)信息,例如:

==27138== Conditional jump or move depends on uninitialised value(s)
==27138== at 0x55F4CEC: __wcsnlen_avx2 (strlen-avx2.S:103)
==27138== by 0x5522EC1: wcsrtombs (wcsrtombs.c:104)
==27138== by 0x54A8B20: wcstombs (wcstombs.c:34)
==27138== by 0x4EDACC2: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F3EE4A: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4E1D7: Rf_eval (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F5066D: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4569D: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4E1D7: Rf_eval (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F5066D: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4E3A1: Rf_eval (in /usr/lib/R/lib/libR.so)
==27138== by 0x4EE5176: ??? (in /usr/lib/R/lib/libR.so)
==27138==

Or maybe…

或许…

==27138== Invalid read of size 32
==27138== at 0x55F4C91: __wcsnlen_avx2 (strlen-avx2.S:62)
==27138== by 0x5522EC1: wcsrtombs (wcsrtombs.c:104)
==27138== by 0x54A8B20: wcstombs (wcstombs.c:34)
==27138== by 0x4EDACC2: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F3EE4A: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4E1D7: Rf_eval (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F5066D: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4569D: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4E1D7: Rf_eval (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F5066D: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4E3A1: Rf_eval (in /usr/lib/R/lib/libR.so)
==27138== by 0x4EE5176: ??? (in /usr/lib/R/lib/libR.so)
==27138== Address 0x1fb9d5d0 is 0 bytes inside a block of size 12 alloc'd
==27138== at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27138== by 0x4F7B1B0: R_chk_calloc (in /usr/lib/R/lib/libR.so)
==27138== by 0x4EDAC3D: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F3EE4A: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4E1D7: Rf_eval (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F5066D: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4569D: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4E1D7: Rf_eval (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F5066D: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F4E3A1: Rf_eval (in /usr/lib/R/lib/libR.so)
==27138== by 0x4EE5176: ??? (in /usr/lib/R/lib/libR.so)
==27138== by 0x4F3EE4A: ??? (in /usr/lib/R/lib/libR.so)
==27138==

Or even…

甚至…

==27138== Invalid read of size 1
==27138== at 0x4C33DA3: strcmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27138== by 0x243B1683: _XimUnRegisterIMInstantiateCallback (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==27138== by 0x24398D32: XUnregisterIMInstantiateCallback (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==27138== by 0x243B1566: _XimRegisterIMInstantiateCallback (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==27138== by 0x24398CBA: XRegisterIMInstantiateCallback (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==27138== by 0x23C8BDFB: TkpOpenDisplay (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23BFA769: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23BFB0AB: TkCreateMainWindow (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23C06CC6: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23C04C7A: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23BFD6C4: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x235E4D5B: ??? (in /usr/lib/R/library/tcltk/libs/tcltk.so)
==27138== Address 0x1f4f12d0 is 0 bytes inside a block of size 9 free'd
==27138== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27138== by 0x243A7D8C: XSetLocaleModifiers (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==27138== by 0x23C8C536: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23C8C4BB: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x243B1566: _XimRegisterIMInstantiateCallback (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==27138== by 0x24398CBA: XRegisterIMInstantiateCallback (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==27138== by 0x23C8BDFB: TkpOpenDisplay (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23BFA769: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23BFB0AB: TkCreateMainWindow (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23C06CC6: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23C04C7A: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23BFD6C4: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== Block was alloc'd at
==27138== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27138== by 0x243A7984: _XlcDefaultMapModifiers (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==27138== by 0x243A7D75: XSetLocaleModifiers (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==27138== by 0x23C8C536: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23C8BDE3: TkpOpenDisplay (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23BFA769: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23BFB0AB: TkCreateMainWindow (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23C06CC6: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23C04C7A: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x23BFD6C4: ??? (in /usr/lib/x86_64-linux-gnu/libtk8.6.so)
==27138== by 0x235E4D5B: ??? (in /usr/lib/R/library/tcltk/libs/tcltk.so)
==27138== by 0x4F12633: ??? (in /usr/lib/R/lib/libR.so)

These are fun to look at :). The last one is a bit messy, below I’ve replaced some parts with “…” to make the structure more apparent:

这些很有趣:)。 最后一个有点混乱,下面我将某些部分替换为“…”以使结构更明显:

==27138== Invalid read of size 1
==27138== at 0x4C33DA3: strcmp (in...)
==27138== by 0x243B1683: _XimUnRegisterIMInst...
==27138== by 0x24398D32: XUnregisterIMInstant...
==27138== by 0x243B1566: _XimRegisterIMInstant...
==27138== by 0x24398CBA: XRegisterIMInstantiat...
==27138== by 0x23C8BDFB: TkpOpenDisplay (in...)
==27138== by 0x23BFA769: ??? (in...)
==27138== by 0x23BFB0AB: TkCreateMainWindow (in...)
==27138== by 0x23C06CC6: ??? (in...)
==27138== by 0x23C04C7A: ??? (in...)
==27138== by 0x23BFD6C4: ??? (in...)
==27138== by 0x235E4D5B: ??? (in...)
==27138== Address .... is 0 bytes inside a block of size 9 free'd
==27138== at 0x4C30D3B: free (in...)
==27138== by 0x243A7D8C: XSetLocaleModifiers (in...)
==27138== by 0x23C8C536: ??? (in...)
==27138== by 0x23C8C4BB: ??? (in...)
==27138== by 0x243B1566: _XimRegisterIMInstant...)
==27138== by 0x24398CBA: XRegisterIMInstant...)
==27138== by 0x23C8BDFB: TkpOpenDisplay (in...)
==27138== by 0x23BFA769: ??? (in...)
==27138== by 0x23BFB0AB: TkCreateMainWindow (in...)
==27138== by 0x23C06CC6: ??? (in...)
==27138== by 0x23C04C7A: ??? (in...)
==27138== by 0x23BFD6C4: ??? (in...)
==27138== Block was alloc'd at
==27138== at 0x4C2FB0F: malloc (in...)
==27138== by 0x243A7984: _XlcDefaultMapModifiers (in...)
==27138== by 0x243A7D75: XSetLocaleModifiers (in...)
==27138== by 0x23C8C536: ??? (in...)
==27138== by 0x23C8BDE3: TkpOpenDisplay (in...)
==27138== by 0x23BFA769: ??? (in...)
==27138== by 0x23BFB0AB: TkCreateMainWindow (in...)
==27138== by 0x23C06CC6: ??? (in...)
==27138== by 0x23C04C7A: ??? (in...)
==27138== by 0x23BFD6C4: ??? (in...)
==27138== by 0x235E4D5B: ??? (in...)
==27138== by 0x4F12633: ??? (in...)

Valgrind memcheck reports two kinds of bugs: memory leaks and memory error. Read more here if you like.

Valgrind memcheck报告两种错误:内存泄漏和内存错误。 如果您愿意,在这里阅读更多

Now bring out the big guns:

现在拿出大枪:

R -d "valgrind --tool=memcheck --leak-check=full 

Step 4: Start the hunt

步骤4:开始搜寻

Create a new empty R script ./check/mypkg.Rcheck/debug-Ex.R . Now, open up the script ./check/mypkg.Rcheck/mypkg-Ex.R and look for the first appearance of cleanEx() . Copy everything above the first appearance of cleanEx() into your new script. Then go to the end of mypkg-Ex.R and copy the last few lines below the word “FOOTER” and paste it to the end of debug-Ex.R . Now your debug-Ex.R should look something like this (where I added # symbols to visually separate the header from the footer):

创建一个新的空R脚本./check/mypkg.Rcheck/debug-Ex.R 。 现在,打开脚本./check/mypkg.Rcheck/mypkg-Ex.R并寻找cleanEx()的首次出现。 将cleanEx()首次出现的所有内容复制到新脚本中。 然后转到mypkg-Ex.R的末尾, mypkg-Ex.R单词“ FOOTER”下面的最后几行复制并粘贴到debug-Ex.R 。 现在您的debug-Ex.R应该看起来像这样(我在其中添加了#个符号,以可视方式将页眉与页脚分开):

pkgname <- "mypkg"
source(file.path(R.home("share"), "R", "examples-header.R"))
options(warn = 1)
library('mypkg')base::assign(".oldSearch", base::search(), pos = 'CheckExEnv')
#####################################################################################################################################
### * <FOOTER>
###
options(digits = 7L)
base::cat("Time elapsed: ", proc.time() - base::get("ptime", pos = 'CheckExEnv'),"\n")
grDevices::dev.off()
###
### Local variables: ***
### mode: outline-minor ***
### outline-regexp: "\\(> \\)?### [*]+" ***
### End: ***
quit('no')

Results

结果

The function causing the error was minDist. It looked like this:

导致错误的函数是minDist。 它看起来像这样:

double minDist_internal1(Rcpp::DataFrame cmbdf, NumericVector point) {int n = cmbdf.nrow();
NumericVector x = cmbdf["x"];
NumericVector y = cmbdf["y"];
NumericVector z = cmbdf["z"];
double px = point[1];
double py = point[2];
double pz = point[3];// Find the minimum distance
double mindot = -1;
for ( int i = 0; i < n; i++ )
{
// Find d(xi, xj)
double dot = x[i]*px + y[i]*py + z[i]*pz;//if ( dot > mindot ) mindot = dot;
if ( true ) mindot = dot;
}return acos(std::min<double>(std::max<double>( mindot, -1),1));
}

Turns out I was indexing starting at 1 instead of 0.

原来我是从1而不是0开始索引。

double px = point[0];
double py = point[1];
double pz = point[2];

Also, if I just used round brackets then this never would have happened.

另外,如果我只是使用圆括号,那么这将永远不会发生。

double px = point(0);
double py = point(1);
double pz = point(2);

That’s because Rcpp will throw an index out of bounds exception when round brackets are used, but square brackets will happily go ahead with out-of-bounds access.

这是因为使用圆括号时,Rcpp会抛出索引超出范围的异常,但是方括号会很高兴地进行越界访问。

Section 4.3 of Writing R Extensions (https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Using-valgrind)

编写R扩展的第4.3节( https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Using-valgrind )

翻译自: https://medium.com/@danielvfryer/valgrind-memcheck-with-r-a-quick-and-dirty-guide-d64567394c57

valgrind 快速

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值