4

エラーを引き起こし、 Hadley Wickham によって提案されたdump.frames()ように使用してすべてのフレームのダンプを書き込む次のコードがあります。

a <- -1
b <- "Hello world!"
bad.function <- function(value)
{
  log(value)                  # the log function may cause an error or warning depending on the value
}

tryCatch( {
             a.local.value <- 42
             bad.function(a)
             bad.function(b)
          },
          error = function(e)
          {
            dump.frames(to.file = TRUE)
          })

R セッションを再起動し、ダンプをロードして問題をデバッグすると、

load(file = "last.dump.rda")
debugger(last.dump)

変数 (a、b、a.local.value) も関数 "bad.function" もフレームのどこにも見つかりません。

これにより、ダンプは私にとってほとんど価値がなくなります。

適切な事後分析のためにすべての変数と関数を表示するにはどうすればよいですか?

の出力debuggerは次のとおりです。

> load(file = "last.dump.rda")
> debugger(last.dump)
Message:  non-numeric argument to mathematical functionAvailable environments had calls:
1: tryCatch({
    a.local.value <- 42
    bad.function(a)
    bad.function(b)
2: tryCatchList(expr, classes, parentenv, handlers)
3: tryCatchOne(expr, names, parentenv, handlers[[1]])
4: value[[3]](cond)

Enter an environment number, or 0 to exit  
Selection: 

PS: デバッグ用に R3.3.2 を RStudio で使用しています。

4

2 に答える 2

4

2016 年 11 月 20 日更新: R のバグではないことに注意してください (Martin Maechler の回答を参照)。再現性のために答えを変更しませんでした。説明されている回避策は引き続き適用されます。

概要

新しいRセッションでバッチジョブのエラーをデバッグしたい場合、dump.frames(to.file = TRUE)現在Rのアンチパターン(またはおそらくバグ)だと思います。

に置き換えたほうがいい

  dump.frames()
  save.image(file = "last.dump.rda")

また

options(error = quote({dump.frames(); save.image(file = "last.dump.rda")}))

それ以外の

options(error = dump.frames)

グローバル環境 ( .GlobalEnv= 通常オブジェクトを作成するユーザー ワークスペース) がダンプに含まれているため、dump.frames(to.file = TRUE).

影響分析

.GlobalEnvエラーの原因となったコードの動作を理解するために、重要な最上位オブジェクト (およびそれらの現在の値 ;-) を失うことはありません!

特に「非対話型」の R バッチ ジョブでエラーが発生した場合は.GlobalEnv、新しく開始された (空の) 対話型ワークスペースでのみデバッグできるため、コール スタック フレーム内のオブジェクトにしかアクセスできなくなります。

上記のコード スニペットを使用すると、通常どおり、新しい R ワークスペースでエラーの原因となったオブジェクトの値を調べることができます。

load(file = "last.dump.rda")
debugger(last.dump)

バックグラウンド

の実装により、ワークスペースにdump.frames変数が作成さlast.dumpれ、コール スタックの環境が格納されます (sys.frames()各環境には、呼び出された関数の「ローカル変数」が含まれます)。次に、 を使用してこの変数をファイルに保存しますsave()

フレーム スタック (コール スタック) は、関数の呼び出しごとに増加します。以下を参照してください?sys.frames

.GlobalEnv には、フレームのリストで番号 0 が与えられます。後続の各関数評価では、フレーム スタックが 1 ずつ増加し、その関数の評価のための [...] 環境が [...] sys.frame によって適切なインデックスと共に返されます。

.GlobalEnvのインデックス番号が 0であることを確認します。

問題のコードによって生成されたダンプのデバッグを開始し、フレーム 1 (0 ではない!) を選択すると、以下parentenvを指す (参照する)変数が表示され.GlobalEnvます。

Browse[1]> environmentName(parentenv)
[1] "R_GlobalEnv"

したがって、 にsys.framesは が含まれていないため、 の他のすべてのオブジェクトなしで のみを格納する.GlobalEnvため、どちらも含まれていないと思います。dump.frames(to.file = TRUE)sys.frames.GlobalEnv

多分私は間違っているかもしれませんが、これは望ましくない効果またはバグのように見えます. ディスカッション歓迎!

参考文献

https://cran.r-project.org/doc/manuals/R-exts.pdf

セクション4.2 R コードのデバッグ(96 ページ)からの抜粋:

last.dump は後で、または別の R セッションで見ることができるため、R のバッチ使用でも事後分析デバッグが可能です。ダンプを保存するように手配する必要があります。コマンドライン フラグ --save を使用して、実行の最後にワークスペースを保存するか、次のような設定を介して

options(error = quote({dump.frames(to.file=TRUE); q()}))

于 2016-11-04T21:06:58.207 に答える