当我通过 `stack exec` `--profile` 选项时找不到可执行文件?

Posted

技术标签:

【中文标题】当我通过 `stack exec` `--profile` 选项时找不到可执行文件?【英文标题】:Executable not found when I pass `stack exec` the `--profile` option? 【发布时间】:2020-04-05 17:40:14 【问题描述】:

谁能帮我理解这个?

$ stack exec -- mvm4x4_amf +RTS -sstderr
mvm4x4_amf: Most RTS options are disabled. Link with -rtsopts to enable them.

$ stack exec --profile -- mvm4x4_amf +RTS -sstderr                                                                                                         
Executable named mvm4x4_amf not found on path: [snip]

我在 Debugging 部分找到了在here 上面尝试的第二个命令的建议。 (搜索词的 13 个匹配项中的第 10 个:“rts”)

使用stack build --profile 重建我的 Stack 项目后,我得到:

$ stack exec --profile -- mvm4x4_amf +RTS -sstderr                                                                                                         
mvm4x4_amf: Most RTS options are disabled. Link with -rtsopts to enable them.

如果我改用这个:

$ stack exec --profile mvm4x4_amf +RTS -sstderr

我的程序运行它们,但我没有得到任何分析信息输出。

如果我“进入”.stack-work/ 目录并“手动执行”(正如我在与此问题相关的其他一些帖子中看到的那样):

$ .stack-work/dist/x86_64-osx/Cabal-2.4.0.1/build/mvm4x4_amf/mvm4x4_amf +RTS -sstderr
mvm4x4_amf: Most RTS options are disabled. Link with -rtsopts to enable them.

然后看来我的可执行文件实际上并不是为分析而构建的。 但是,尝试显式重建它以进行分析不会产生任何操作:

$ stack build --profile :mvm4x4_amf

$

哦,这有帮助吗?:

$ stack exec mvm4x4_amf --rts-options --info
 [("GHC RTS", "YES")
 ,("GHC version", "8.6.5")
 ,("RTS way", "rts_v")
 ,("Build platform", "x86_64-apple-darwin")
 ,("Build architecture", "x86_64")
 ,("Build OS", "darwin")
 ,("Build vendor", "apple")
 ,("Host platform", "x86_64-apple-darwin")
 ,("Host architecture", "x86_64")
 ,("Host OS", "darwin")
 ,("Host vendor", "apple")
 ,("Target platform", "x86_64-apple-darwin")
 ,("Target architecture", "x86_64")
 ,("Target OS", "darwin")
 ,("Target vendor", "apple")
 ,("Word size", "64")
 ,("Compiler unregisterised", "NO")
 ,("Tables next to code", "YES")
 ]

嗯,在更改 cabal 文件选项并重建时,我注意到一些奇怪的事情:

$ stack build --profile :mvm4x4_amf
luminous-0.5.0.0: unregistering (local file changes: luminous.cabal)
luminous> configure (lib + exe)
Configuring luminous-0.5.0.0...
luminous> build (lib + exe)
Preprocessing library for luminous-0.5.0.0..
Building library for luminous-0.5.0.0..
Preprocessing executable 'mvm4x4_amf' for luminous-0.5.0.0..
Building executable 'mvm4x4_amf' for luminous-0.5.0.0..
luminous> copy/register
Installing library in .../.stack-work/install/x86_64-osx/2428dc603454d346facf6484280fa92531e4d7789d3
3c4dd56c39cf70d79bd7e/8.6.5/lib/x86_64-osx-ghc-8.6.5/luminous-0.5.0.0-9ABiH0AyDmV25JxAv1cFEI                                                              
snip
Installing executable mvm4x4_amf in .../.stack-work/install/x86_64-osx/2428dc603454d346facf6484280fa
92531e4d7789d33c4dd56c39cf70d79bd7e/8.6.5/bin                                                                                                             
snip
Registering library for luminous-0.5.0.0..

$ stack exec which mvm4x4_amf
.../.stack-work/install/x86_64-osx/9af8b70f7f84a02189b610f95c8d289ab7d743df5c23a5d5d43b30afe0c02b7c/
8.6.5/bin/mvm4x4_amf                                                                                                                                      

Stack 似乎在与安装它的目录不同的目录中找到了我的 mvm4x4_amf 可执行文件! 我读对了吗? 我应该担心吗?

哦,供参考:

$ stack --version
Version 2.1.3, Git revision 0fa51b9925decd937e4a993ad90cb686f88fa282 (7739 commits) x86_64 hpack-0.31.2

【问题讨论】:

【参考方案1】:

啊哈!你必须这样做:

$ stack exec --profile mvm4x4_amf --rts-options -sstderr

使用该命令,我得到了预期的分析结果:

 294,885,845,152 bytes allocated in the heap
   3,900,063,256 bytes copied during GC
     160,061,616 bytes maximum residency (57 sample(s))
       6,223,696 bytes maximum slop
             152 MB total memory in use (0 MB lost due to fragmentation)

                                     Tot time (elapsed)  Avg pause  Max pause
  Gen  0     282964 colls,     0 par    6.696s   6.863s     0.0000s    0.0013s
  Gen  1        57 colls,     0 par    0.928s   1.048s     0.0184s    0.1195s

  INIT    time    0.000s  (  0.003s elapsed)
  MUT     time  217.655s  (221.658s elapsed)
  GC      time    7.624s  (  7.911s elapsed)
  RP      time    0.000s  (  0.000s elapsed)
  PROF    time    0.000s  (  0.000s elapsed)
  EXIT    time    0.000s  (  0.000s elapsed)
  Total   time  225.279s  (229.571s elapsed)

  %GC     time       0.0%  (0.0% elapsed)

  Alloc rate    1,354,833,854 bytes per MUT second

  Productivity  96.6% of total user, 96.6% of total elapsed

在我的正常程序输出之后。

还有:

$ stack exec --profile which mvm4x4_amf                                                                                                                    
.../.stack-work/install/x86_64-osx/2428dc603454d346facf6484280fa92531e4d7789d33c4dd56c39cf70d79bd7e/
8.6.5/bin/mvm4x4_amf                                                                                                                                      

所以,我猜,--profile 选项将stack exec 命令“引导”到不同的install/ 子目录? 我想这是有道理的。

【讨论】:

【参考方案2】:
$ stack exec -- mvm4x4_amf +RTS -sstderr
mvm4x4_amf: Most RTS options are disabled. Link with -rtsopts to enable them.

$ stack exec --profile -- mvm4x4_amf +RTS -sstderr
Executable named mvm4x4_amf not found on path: [snip]

发生这种情况是因为使用和不使用分析信息构建的可执行文件实际上是非常不同的可执行文件。这是因为发出分析信息的成本非常高,因此会显着减慢执行速度,因此当您在没有--profile 的情况下进行构建时,所有这些额外的代码都会被剥离以提高性能。

您的第二次调用失败,因为您没有构建程序的分析可执行文件。简而言之,.stack-work 中有多个目录,其中包含使用不同选项构建的多组二进制文件,因此stack exec --profile 查找“分析二进制文件”目录,在您的情况下该目录为空。

使用 stack build --profile 重建我的 Stack 项目后,我得到:

$ stack exec --profile -- mvm4x4_amf +RTS -sstderr                    
mvm4x4_amf: Most RTS options are disabled. Link with -rtsopts to enable them.

这个调用是正确的。正如错误提示的那样,您现在需要使用-rtsopts构建您的可执行文件,以使您的可执行文件接受您要传递给它的 RTS 选项。

如果我改用这个:

$ stack exec --profile mvm4x4_amf +RTS -sstderr

我的程序运行它们,但我没有得到任何分析信息输出。

这里的问题是 stack 本身就是一个 Haskell 问题,因此您的 +RTS -sstderr 选项被 stack 消耗,而不是传递给您的二进制文件。你绝对需要那些--(或者,你可以使用--rts-options <options>,它告诉堆栈将+RTS <options>传递给你的二进制文件。

【讨论】:

以上是关于当我通过 `stack exec` `--profile` 选项时找不到可执行文件?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript通过new Error() hack方法从函数体内部获取函数名

使用 Stack 分析构建

无法通过Runtime.exec运行命令

用于从表中获取记录的 SQL 查询需要很长时间,但是当我运行 exec sp_updatestats 时按预期工作

Terraform `local-exec` 设置本地别名

导入库不能与 exec 函数一起使用?