Các phương pháp hay nhất với Nuget: Gỡ lỗi hay Phát hành?


92

Hiện tại, tôi đóng gói các bản dựng phát hành với Nuget cho các bản dựng chính thức cho nuget.org, nhưng tôi đóng gói các bản dựng gỡ lỗi bằng Nuget cho các lần đẩy mã nguồn tới Symbolource.org.

CHỈNH SỬA: (Jon Skeet, với một số thiên vị từ việc phát triển Noda Time)

NuGet hiện hỗ trợ đẩy lên cả thư viện NuGet Symbolource.org (hoặc các máy chủ tương tự), như được ghi lại . Thật không may, có hai yêu cầu trái ngược nhau ở đây:

  • Khi chỉ sử dụng một thư viện mà không cần gỡ lỗi, bạn thực sự muốn có một bản phát hành. Rốt cuộc, đó là những gì mà các bản dựng phát hành dành cho.
  • Khi gỡ lỗi vào thư viện cho mục đích chẩn đoán, bạn thực sự muốn có một bản dựng gỡ lỗi với tất cả các tối ưu hóa thích hợp bị tắt. Rốt cuộc, đó là những gì các bản dựng gỡ lỗi dành cho.

Điều đó sẽ ổn thôi, nhưng NuGet không (theo như tôi có thể nói) cho phép cả bản phát hành và bản gỡ lỗi được xuất bản theo cách hữu ích, trong cùng một gói.

Vì vậy, các lựa chọn là:

  • Phân phối các bản dựng gỡ lỗi cho mọi người (như được hiển thị trong ví dụ trong tài liệu) và hoạt động với bất kỳ lần truy cập kích thước và hiệu suất nào.
  • Phân phối các bản dựng phát hành cho mọi người và sống với trải nghiệm gỡ lỗi đôi chút.
  • Thực hiện một chính sách phân phối thực sự phức tạp, có khả năng cung cấp các gói phát hành và gỡ lỗi riêng biệt.

Hai điều đầu tiên thực sự hiểu rõ về ảnh hưởng của sự khác biệt giữa bản dựng gỡ lỗi và bản phát hành ... mặc dù cần lưu ý rằng cũng có sự khác biệt lớn giữa việc muốn bước vào mã của thư viện vì bạn muốn kiểm tra một số hành vi và muốn để gỡ lỗi mã của thư viện vì bạn tin rằng mình đã tìm thấy lỗi. Trong trường hợp thứ hai, có lẽ tốt hơn là lấy mã của thư viện dưới dạng giải pháp Visual Studio và gỡ lỗi theo cách đó, vì vậy tôi không phải chú ý quá nhiều đến tình huống đó.

Sự cám dỗ của tôi là chỉ tiếp tục với các bản dựng phát hành, với kỳ vọng rằng tương đối ít người sẽ cần gỡ lỗi và những người không bị ảnh hưởng nhiều bởi các tối ưu hóa trong bản phát hành. (Dù sao thì trình biên dịch JIT cũng thực hiện hầu hết việc tối ưu hóa.)

Vì vậy, có những lựa chọn khác mà chúng tôi đã không xem xét? Có những cân nhắc nào khác để đưa ra số dư không? Việc đẩy các gói NuGet sang SymbolSource có đủ mới mà "phương pháp hay nhất" thực sự chưa được thiết lập không?


2
Tôi cũng định hỏi câu hỏi tương tự - mặc dù hiện tại tôi cũng đang đẩy cấu hình Phát hành sang nguồn biểu tượng, vì tôi chỉ đang sử dụng nuget pack ... -Symbolvà đẩy các gói đã tạo ...
Jon Skeet

1
Tôi cảm thấy mình nên gửi phần Q / A này cho những người đứng sau NuGet và xem liệu họ có thể cân nhắc về nó hay không.
gzak

Nướng đăng nhập vào gói của bạn và sau đó chỉ xuất bản bản dựng phát hành. Bạn có thể cho phép chèn trình ghi nhật ký, điều này sẽ cung cấp cho người tiêu dùng thiết lập ghi nhật ký theo sở thích của họ.
CShark

Câu trả lời:


31

Nói về SymbolSource, tôi tin rằng cách tốt nhất là:

  1. Chỉ đẩy gói nội dung + nhị phân phát hành lên nuget.org (hoặc bất kỳ nguồn cấp dữ liệu sản xuất nào khác)
  2. Đẩy gói nội dung + nhị phân gỡ lỗi vào nguồn cấp dữ liệu phát triển:
    • tại chỗ
    • trên myget.org
    • trên nuget.org dưới dạng gói phát hành trước.
  3. Đẩy cả hai gói ký hiệu + nhị phân phát hành và gỡ lỗi vào Symbolource.org hoặc bất kỳ kho ký hiệu nào khác.

Trong khi chúng ta đang ở đó, có một quan niệm sai lầm phổ biến rằng bản dựng phát hành và gỡ lỗi trong .NET thực sự khác nhau nhiều, nhưng tôi giả định rằng sự khác biệt ở đây là do nhiều mã khác nhau có thể có hoặc có thể không được bao gồm trong cả hai bản dựng, như Gỡ lỗi .Asserts.

Điều đó nói rằng, việc đẩy cả hai cấu hình lên SymbolSource thực sự đáng giá, bởi vì bạn không bao giờ biết khi nào mình cần gỡ lỗi mã sản xuất. Từ xa trong sản xuất để làm cho nó khó hơn. Bạn sẽ cần sự trợ giúp từ công cụ của mình khi điều đó xảy ra. Điều mà tôi rõ ràng không mong muốn ở bất cứ ai.

Vẫn còn một vấn đề cần xem xét liên quan đến việc lập phiên bản: có đúng là có 2 gói khác nhau (bản dựng trong gỡ lỗi và bản phát hành) dùng chung 1 số phiên bản không? SymbolSource sẽ chấp nhận điều đó, vì nó trích xuất các gói và lưu trữ các tệp nhị phân trong các nhánh chế độ xây dựng riêng biệt, NẾU CHỈ NuGet được phép gắn thẻ các gói cho phù hợp. Hiện tại không có cách nào để xác định xem một gói đang gỡ lỗi hay chế độ phát hành.


Phần "xuất bản hai bản dựng lên NuGet" là một chút khó khăn. Tôi luôn xuất bản bản phát hành của Noda Time, với lý do là tôi phải chọn giữa hai. (Tôi có một tệp nuspec, thay vì làm nó chỉ từ dự án C #.) Bạn đề cập đến việc gỡ lỗi mã sản xuất như thể điều đó khó hơn đáng kể với chỉ một bản dựng phát hành - mặc dù phần trước "chúng không khác nhau nhiều". Tôi biết về các NOP trong các bản dựng gỡ lỗi, và rõ ràng là Debug.Assertv.v. - nhưng bạn có thể mở rộng (trong câu trả lời của mình) về các tác động khi gỡ lỗi không? Nó tệ như thế nào khi sử dụng bản phát hành?
Jon Skeet

Ý tôi chỉ là bạn muốn có sẵn các biểu tượng cho tất cả các mã nhị phân đang sử dụng: nếu có cả bản dựng gỡ lỗi và bản phát hành, bạn sẽ muốn cung cấp các biểu tượng cho cả hai. Chúng không cần khác nhau nhiều về mã, nhưng chúng sẽ khác nhau về tổng kiểm tra, điều này làm cho việc tải các biểu tượng không thể thực hiện được nếu không có một số hack.
TripleEmcoder

1
Đúng. Giải pháp khả thi của tôi là chỉ bao giờ phát hành các tệp nhị phân Phát hành, nhưng tôi lo lắng về việc điều đó sẽ ảnh hưởng đến mức độ nào về mặt gỡ lỗi. Ví dụ: việc thiếu NOP có nghĩa là bạn không thể thêm các điểm ngắt?
Jon Skeet

Vấn đề là với tối ưu hóa JIT nhiều hơn là tối ưu hóa thời gian xây dựng. Vì vậy, nếu bạn đẩy các gói chế độ phát hành và khuyên bạn nên sử dụng COMPLUS_ZapDisable = 1 khi cần gỡ lỗi, điều đó sẽ đủ tốt cho tôi. Vẫn NuGet nên cho phép gỡ lỗi và phát hành cùng nhau theo một cách nào đó.
TripleEmcoder

Tôi không biết Symbolssource.org tồn tại. Là một cơn ngứa mà tôi đã nhiều lần phải gãi, tôi hoan nghênh nó.
Remus Rusanu

4

Tôi hoàn toàn đồng ý với kết luận của bạn. Các gói NuGet với RELEASE và SymbolSource có gỡ lỗi. Có vẻ như khá hiếm khi bước trực tiếp vào các gói và thỉnh thoảng có thể chấp nhận được lỗi sai khi gỡ lỗi khi bật tối ưu hóa.

Nếu thực sự có vấn đề, tôi nghĩ giải pháp lý tưởng là nhờ NuGet hỗ trợ. Ví dụ, hãy tưởng tượng nếu khi gỡ lỗi, nó có thể thay thế DLL phát hành bằng DLL có trong gói SymbolSource.

Lý tưởng nhất, điều gì sẽ xảy ra sau đó là nuget pack SomePackage -Symbolschống lại một phiên bản phát hành sẽ tạo ra một gói nuget phát hành, nhưng một gói ký hiệu gỡ lỗi. Và plugin VS sẽ được cập nhật để đủ thông minh để nhìn thấy sự liên kết và kéo vào các cụm từ Gỡ lỗi khi chạy trong trình gỡ lỗi và tải chúng thay thế. Hơi điên rồ, nhưng sẽ rất thú vị.

Tuy nhiên, tôi không thấy có đủ người phàn nàn về điều này rằng nó đáng giá vào lúc này.

Nhóm NuGet chấp nhận các yêu cầu kéo. :)


Tôi không chắc mình hiểu câu thứ hai của bạn - Tôi nghi ngờ OP (trước khi tôi chỉnh sửa) đang thực hiện đẩy thủ công đến SymbolSource cho các bản dựng gỡ lỗi. Bạn có hình dung ra các vấn đề nghiêm trọng nếu PDB của phiên bản phát hành kết thúc trong SymbolSource thay vì phiên bản gỡ lỗi không? Hay đó là những gì bạn đang biện hộ, và tôi chỉ hiểu sai?
Jon Skeet

3
"Tuy nhiên, tôi không thấy có đủ người phàn nàn về điều này rằng nó đáng giá vào lúc này." Có lẽ họ không phàn nàn, nhưng nếu bạn hỏi một mẫu người dùng rằng họ nghĩ gì về điều này, tôi cá rằng bạn sẽ thấy rằng hầu hết mọi người sẽ thừa nhận một chút nhầm lẫn ở bước cụ thể này (những gì sẽ xuất bản lên NuGet.org và SymbolSource .org). Nếu bạn hỏi họ đã chọn cái gì, có lẽ bạn sẽ thấy rằng không có cách làm nào được thống nhất cả, mọi người chỉ làm việc của riêng mình.
gzak

7
Tôi muốn khiếu nại về điều này, tôi phải đăng ký ở đâu?
Alex

Một khi bạn có NuGets nội bộ và bạn bắt đầu triển khai chúng tới một máy chủ biểu tượng ... thì chắc chắn bạn sẽ muốn gỡ lỗi chúng .... và mặc dù bạn có thể xem qua mã, bạn sẽ kết thúc bằng "Không thể lấy giá trị của biến cục bộ hoặc đối số ... nó đã được tối ưu hóa ". Như Phil đã đề cập ... NẾU nuget có cách tải các dlls gỡ lỗi trong chế độ gỡ lỗi và giải phóng các dlls ở chế độ phát hành (từ các gói nuget), đây sẽ là điều cuối cùng. Cho đến lúc đó, chúng tôi bị mắc kẹt với trình chuyển đổi gói
Nuget

1
Tôi đồng tình, đây sẽ là một cải tiến sản phẩm tốt đẹp.
htm11h

2

Đã 8 năm kể từ bài viết của OP, vì vậy tôi sẽ cung cấp cho nó một bản crack với những gì được sử dụng ngày nay.

Có 2 cách để " bước vào " gói NuGet:

1. Phân phối PDBs

.symbols.nupkggói biểu tượng được coi là kế thừa và đã được thay thế bằng .snupkgcác gói được xuất bản lên Máy chủ biểu tượng . Nó được hỗ trợ bởi tất cả các nhà cung cấp lớn, như NuGet.org, Azure DevOps ( mặc dù kém mượt mà hơn ), v.v.

Dưới đây là các hướng dẫn chính thức . Chỉ cần thêm hai dòng này vào tệp csproj:

<PropertyGroup>
  <IncludeSymbols>true</IncludeSymbols>
  <SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>

Về phía người tiêu dùng, hãy đảm bảo rằng IDE của bạn được định cấu hình cho Máy chủ biểu tượng NuGet.org (hoặc Azure, v.v.) để cho phép bước vào mã gói khi gỡ lỗi.

2. Liên kết nguồn. Liên kết mã thực tế

Trong một số trường hợp, các PDB có thể ẩn một số chi tiết cụ thể của mã nguồn do tối ưu hóa MSIL / JIT. Vì vậy, có một cách để " Bước vào " nguồn thực sự của NuGet của bạn trong khi gỡ lỗi. Nó được gọi là Liên kết nguồn từ Tổ chức .NET - " một hệ thống bất khả tri ngôn ngữ và kiểm soát nguồn để cung cấp trải nghiệm gỡ lỗi nguồn cho các tệp nhị phân ".

Nó được hỗ trợ bởi Visual Studio 15.3+ và tất cả các nhà cung cấp chính (cũng hỗ trợ các repo riêng).

Việc thiết lập ( tài liệu chính thức ) là điều không cần thiết - chỉ cần thêm phần phụ thuộc phát triển vào tệp dự án (phụ thuộc vào loại repo của bạn) cùng với một số cờ:

<PropertyGroup>
    <PublishRepositoryUrl>true</PublishRepositoryUrl>
    <EmbedUntrackedSources>true</EmbedUntrackedSources>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

Kiểm tra thêm về chủ đề này trong " 5 bước để gói NuGet tốt hơn ".


1

Ví dụ trong Tạo và Xuất bản Gói Biểu tượng tham chiếu các tệp trong thư mục Gỡ lỗi dưới dạng nguồn cho các tệp dll và pdb.

Chỉ định nội dung gói ký hiệu

Một gói biểu tượng có thể được xây dựng theo quy ước, từ một thư mục được cấu trúc theo cách được mô tả trong phần trước, hoặc nội dung của nó có thể được chỉ định bằng cách sử dụng phần tệp. Nếu bạn muốn xây dựng gói mẫu được mô tả trước đây, bạn có thể đặt gói này vào tệp nuspec của mình:

<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>

Vì mục đích của việc xuất bản các ký hiệu là để cho phép người khác xem qua mã của bạn khi gỡ lỗi, nên có vẻ như thận trọng nhất là xuất bản một phiên bản mã dành cho gỡ lỗi mà không có các tối ưu hóa có thể ảnh hưởng đến bước mã.


Vâng, đó là những gì ví dụ - nhưng tôi không muốn kết thúc với khả năng gỡ lỗi ghi đè mong muốn của hầu hết các nhà phát triển chỉ chạy phiên bản phát hành. Vấn đề là NuGet không có cách xuất bản cả phiên bản phát hành và gỡ lỗi, theo như tôi có thể nói. (Nó cũng sẽ là một cơn đau nhẹ cho tôi để xuất bản cả hai, vì nó có nghĩa là tạo được nêu ra một tập hợp các cấu hình, cho ký debug xây dựng ...)
Jon Skeet

Ở đây chúng ta có một chút chủ quan. Thông thường, lựa chọn của tôi cho "phương pháp hay nhất" sẽ là lựa chọn mà tác giả đề xuất, rõ ràng hoặc ẩn ý, ​​bởi vì tôi cho rằng họ có cái nhìn sâu sắc hơn (hoặc giám sát, trong trường hợp giả định kết thúc bằng ví dụ) so với tôi. Tôi nghĩ rằng các ký hiệu phải phù hợp với phiên bản tôi đang sử dụng. Tôi thường sẽ không sử dụng một gói mà tôi nghĩ rằng tôi có thể sẽ phải gỡ lỗi, trừ khi nguồn là công khai và tôi có thể biên dịch từ đầu nếu cần, vì vậy việc thiếu bản dựng gỡ lỗi được đóng gói không đặc biệt quan trọng.
tvanfosson

Trong trường hợp của tôi, nếu ai đó cần gỡ lỗi Noda Time vì họ tin rằng có lỗi trong Noda Time, tốt hơn hết họ nên tải xuống nguồn (tất nhiên là họ có thể làm được). Tuy nhiên, nó vẫn hữu ích khi có thể bước vào mã nguồn Noda Time chỉ để xem điều gì đang xảy ra. Về cơ bản, tôi nghĩ rằng có (ít nhất) hai kịch bản khác nhau để gỡ lỗi, với các giải pháp khác nhau ...
Jon Skeet

Một điều tôi thích nghĩ đến là bản thân .NET: Tôi nghĩ rằng có thể an toàn khi nói rằng Microsoft xuất bản các bản dựng phát hành và không gỡ lỗi các bản dựng của .NET. Một phiên bản phát hành ngụ ý một mức chất lượng và độ ổn định nhất định, vì vậy ý ​​tưởng là bạn hiếm khi cần phải bước vào mã để chẩn đoán mọi thứ.
gzak

2
Tuy nhiên, đó cũng là một tâm lý khá “kín cổng cao tường”. Tôi nhận thấy rằng trong thế giới nguồn mở, người ta mong đợi hơn khi có thể bước vào mã "bản phát hành ổn định" của các thư viện khác nhau không phải vì mọi thứ bị hỏng, mà vì đôi khi tài liệu tốt nhất là chỉ xem thư viện là gì. đang làm.
gzak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.