Nugetのベストプラクティス:デバッグまたはリリース?


89

現在、公式ビルド用のリリースビルドはNugetでnuget.orgにパッケージ化していますが、シンボルソースプッシュ用にデバッグビルドをNugetでパッケージ化し、symbolsource.orgにプッシュしています。

編集:(Jon Skeet、Noda Time開発からの偏見あり)

ドキュメントに記載されているように、NuGetはNuGetギャラリー symbolsource.org(または同様のサーバー)の両方へのプッシュをサポートするようになりました。残念ながら、ここには2つの矛盾する要件があります。

  • デバッグを必要とせずにライブラリを使用する場合、リリースビルドが本当に必要です。結局のところ、それがリリースビルドの目的です。
  • 診断目的でライブラリにデバッグする場合、適切な最適化をすべて無効にしたデバッグビルドが本当に必要です。結局のところ、それがデバッグビルドの目的です。

それでもかまいませんが、NuGetでは(私が知る限り)リリースビルドとデバッグビルドの両方を同じパッケージで便利な方法で公開することはできません。

したがって、選択肢は次のとおりです。

  • (ドキュメントの例に示されているように)デバッグビルドをすべての人に配布し、サイズやパフォーマンスに影響を与えずに実行します。
  • リリースビルドをすべての人に配布し、わずかに障害のあるデバッグエクスペリエンスでライブします。
  • 非常に複雑な配布ポリシーを採用し、個別のリリースパッケージとデバッグパッケージを提供する可能性があります。

最初の2つは、デバッグビルドとリリースビルドの違いによる影響を実際に要約したものです。ただし、動作を確認するためにライブラリのコードにステップインすることと、バグを発見したと思われるため、ライブラリのコードをデバッグします。2番目のケースでは、おそらくライブラリのコードをVisual Studioソリューションとして取得し、そのようにデバッグする方が良いので、その状況にあまり注意を払っていません。

私の誘惑は、リリースビルドをそのまま維持することです。デバッグする必要のある人は比較的少なく、リリースビルドの最適化による影響はそれほど大きくないはずです。(いずれにしても、JITコンパイラーはほとんどの最適化を行います。)

それで、私たちが考慮していなかった他のオプションはありますか?バランスを傾ける他の考慮事項はありますか?NuGetパッケージをSymbolSourceにプッシュすることは、「ベストプラクティス」が実際に確立されていないほど新しいものですか?


2
私は同じ質問をしようとしていましたが、現在nuget pack ... -Symbol、生成されたパッケージを使用してプッシュしているだけなので、Release構成もシンボルソースにプッシュしています...
Jon Skeet

1
私はこのQ / AセッションをNuGetの背後にいる人々に提出し、彼らがそれについて検討できるかどうかを確認する必要があると感じています。
gzak 2013

パッケージにログインをベイクし、リリースビルドのみを公開します。消費者が自分の好みに応じてロギングを設定できるようにするロガー注入を許可できます。
CShark

回答:


29

SymbolSourceについて言えば、ベストプラクティスは次のとおりであると思います。

  1. リリースバイナリ+コンテンツパッケージをnuget.orgのみ(またはその他の本番環境フィード)にプッシュする
  2. デバッグバイナリ+コンテンツパッケージを開発フィードにプッシュします。
    • 敷地内に
    • myget.org
    • nuget.orgでプレリリースパッケージとして。
  3. リリースとデバッグのバイナリ+シンボルパッケージの両方をsymbolsource.orgまたはその他のシンボルストアにプッシュします。

私たちがそれをしている間、.NETでのリリースビルドとデバッグビルドは実際に大きく異なるというのはよくある誤解ですが、Debugのように、どちらのビルドにも含まれる、または含まれない可能性があるさまざまなコードのために、ここに違いがあると想定しています.Asserts。

とは言え、どちらの構成もSymbolSourceにプッシュする価値があります。本番用コードをデバッグする必要がある時期がわからないためです。生産をリモートで行うことで、より困難になります。あなたはそれが起こったときにあなたがあなたのツールから得ることができる助けを必要とするでしょう。これは明らかに誰にも望まないことです。

バージョニングに関して考慮すべき問題がまだあります:1つのバージョン番号を共有する2つの異なるパッケージ(デバッグとビルドでビルド)を持つことは正しいですか?SymbolSourceはパッケージを抽出し、バイナリを個別のビルドモードブランチに格納するため、それを受け入れます。NuGetがそれに応じてパッケージにタグを付けることができる場合のみです。現在、パッケージがデバッグモードかリリースモードかを判別する方法はありません。


「2つのビルドをNuGetに公開する」という部分は注意が必要です。Noda Timeのリリースビルドは、2つの中から選択しなければならないという理由で、常に公開してきました。(C#プロジェクトからだけではなく、nuspecファイルを持っています。)生産コードのデバッグは、リリースビルドだけではかなり困難であると述べています。私はデバッグビルドのNOPを知っていますし、明らかにDebug.Assert他にもありますが、デバッグ時の影響について(回答で)拡張できますか?リリースビルドを使用するのはどれくらい悪いですか?
Jon Skeet、2013

私が意味したのは、使用中のすべてのバイナリでシンボルを使用できるようにすることだけでした。デバッグビルドとリリースビルドの両方が実際にある場合は、両方にシンボルを提供する必要があります。コードの点でそれほど異なる必要はありませんが、チェックサムが異なるため、ハッキングしないとシンボルをロードできません。
TripleEmcoder 2013

1
正しい。私の可能な解決策はリリースバイナリのみをリリースすることですが、デバッグに関してどれほどの損害が発生するか心配です。たとえば、NOPがないということは、ブレークポイントを追加できないということですか?
Jon Skeet、2013

問題は、ビルド時の最適化よりもJITの最適化にあります。したがって、リリースモードパッケージをプッシュし、デバッグが必要なときにCOMPLUS_ZapDisable = 1の使用を推奨する場合、それで十分です。それでも、NuGetは何らかの方法でデバッグとリリースを一緒に許可する必要があります。
TripleEmcoder 2013

私はsymbolssource.orgが存在するという考えを持っていませんでした。私は何度も掻く必要があったかゆみとして、それを歓迎します。
Remus Rusanu 2013

4

私はあなたの結論に完全に同意します。RELEASE付きのNuGetパッケージとデバッグ付きのSymbolSource。パッケージに直接ステップインすることは非常にまれであり、最適化を有効にしてデバッグを誤って実行することは許容できる場合があります。

本当に問題があった場合、理想的な解決策はNuGetでサポートすることだと思います。たとえば、デバッグ時にリリースDLLをSymbolSourceパッケージに含まれているDLLに置き換えることができると想像してください。

理想的にはnuget pack SomePackage -Symbols、リリースバージョンに対してリリースnugetパッケージが作成され、デバッグシンボルパッケージが作成されます。そして、VSプラグインは、関連付けを確認し、デバッガーで実行しているときにデバッグアセンブリをプルし、代わりにそれらを読み込むのに十分スマートになるように更新されます。ちょっとクレイジーですが、面白いでしょう。

しかし、現時点でそれだけの価値があると思うほど、これについて文句を言う人が十分にいないようです。

NuGetチームはプルリクエストを受け入れます。:)


2番目の文が理解できたとは思いません。OP(編集前)がデバッグビルドのためにSymbolSourceに手動でプッシュしていたと思います。リリースバージョンのPDBがデバッグバージョンではなくSymbolSourceになる場合、重大な問題を想定していますか?それとも、あなたが主張していたもので、私は誤解しているだけですか?
Jon Skeet

3
「しかしながら、現時点でそれだけの価値があると思うほど、これについて不満を言う人は十分にいない。」おそらく彼らは文句を言っていませんが、ユーザーのサンプルにこれについてどう思うかを尋ねた場合、ほとんどの人はこの特定のステップ(NuGet.orgとSymbolSourceに公開するもの)で多少の混乱を認めるでしょう。 .org)。彼らが何を選んだのかを尋ねた場合、おそらく合意された単一のプラクティスはなく、誰もが自分のことをするだけです。
gzak

7
これについて文句を言いたいのですが、どこにサインアップすればよいですか?
Alex

内部NuGetがあり、それらをシンボルサーバーに展開し始めると、それらをデバッグする必要が生じます。コードをステップ実行できても、最終的には、「値を取得できません。ローカル変数または引数...最適化されました。」Philが言及しているように... nugetがデバッグモードでデバッグdllをロードし、リリースモードでdllをリリースする(nugetパッケージから)方法がある場合、これは究極の方法です。それまでは、Nugetパッケージスイッチャーに
悩まされていました

1
私は同意します、これは素晴らしい製品強化になるでしょう。
htm11h 2017

1

シンボルパッケージの作成と公開の例では、dllおよびpdbファイルのソースとして、Debugディレクトリのファイルを参照しています。

シンボルパッケージの内容の指定

シンボルパッケージは、前のセクションで説明した方法で構造化されたフォルダーから規則に従って構築するか、またはファイルセクションを使用してその内容を指定できます。前述のサンプルパッケージをビルドする場合は、これをnuspecファイルに追加できます。

<files>
  <file src="Full\bin\Debug\*.dll" target="lib\net40" /> 
  <file src="Full\bin\Debug\*.pdb" target="lib\net40" /> 
  <file src="Silverlight\bin\Debug\*.dll" target="lib\sl40" /> 
  <file src="Silverlight\bin\Debug\*.pdb" target="lib\sl40" /> 
  <file src="**\*.cs" target="src" />
</files>

シンボルを公開する目的は、デバッグ時に他のユーザーがコードをステップ実行できるようにすることであるため、コードのステップ実行に影響する可能性のある最適化なしのデバッグ用のバージョンのコードを公開することが最も賢明なようです。


はい、それが例で行うことですが、ほとんどの開発者がリリースバージョンだけを実行したいという欲求を上書きしてデバッグする機能に終わりはありません。問題は、私の知る限り、NuGetにはリリースビルドとデバッグビルドの両方を公開する方法がないことです。(署名されたデバッグビルド用にさらに別の構成セットを作成することを意味するため、両方を公開するのも少し苦痛です...)
Jon Skeet

ここで、主観に少し触れます。通常、私が「ベストプラクティス」を選択するのは、著者が明示的または暗黙的に推奨する方法です。なぜなら、私は彼らが私よりも洞察(または、例で終わる仮定の場合は見落とし)を持っていると考えているからです。個人的には、記号は使用しているバージョンと一致している必要があると思います。私は通常、ソースが公開されており、必要に応じて最初からコンパイルできる場合を除いて、デバッグする必要があると思われるパッケージを使用しません。そのため、パッケージ化されたデバッグビルドがないことは特に重要ではありません。
tvanfosson 2013

私の場合、野田タイムにバグがあると思って誰かが野田タイムをデバッグする必要がある場合は、ソースをダウンロードすることをお勧めします(もちろん、そうすることができます)。ただし、何が起こっているのかを確認するためだけにNoda Timeのソースコードにステップインできると便利です。基本的に私は(少なくとも)デバッグには2つの異なるシナリオがあり、さまざまなソリューションがあると思います...
Jon Skeet

私が考えたいことの1つは.NET自体です。Microsoftは.NETのデバッグビルドではなくリリースビルドを公開していると言っても安全だと思います。リリースビルドは、一定レベルの品質と安定性を意味するため、物事を診断するためにコードにステップインする必要はほとんどないはずです。
gzak 2013

2
ただし、それはかなり「クローズドソース」の考え方でもあります。オープンソースの世界では、さまざまなライブラリの「安定版リリース」のコードにステップインできることが期待されています。これは、物事が壊れているためではなく、ライブラリが何であるかを確認することが最良のドキュメントである場合があるためです。やっている。
gzak 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.