성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Java - How to use the Foreign Funct...
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>닷넷 응용 프로그램을 위한 PDB 옵션 - full, pdbonly, portable, embedded</h1> <p> PDB에 대해서는 이미 충분히 설명을 했었죠. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > PDB 이야기 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/309'>https://www.sysnet.pe.kr/2/0/309</a> </pre> <br /> C# 컴파일러(csc.exe)의 경우 PDB 생성을 위한 -debug 옵션으로 4가지 값(full, pdbonly, portable, embedded)이 가능한 것을 볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > -debug:{full|pdbonly|portable|embedded} Specify debugging type ('full' is default, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the target .dll or .exe) </pre> <br /> 해당 옵션은 비주얼 스튜디오에서 C# 프로젝트 설정의 "Build" / "Advanced" - "Output" / "Debugging information" 옵션으로 제어할 수 있지만 직접 csproj 파일에 <DebugType />으로 지정해도 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <DebugType>portable</DebugType> </pre> <br /> full이 기본값이고, full과 pdbonly의 차이는 다음의 문서에 따라,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > -debug (C# Compiler Options) ; <a target='tab' href='https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/debug-compiler-option'>https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/debug-compiler-option</a> </pre> <br /> 실행 시점에 디버거를 연결했을 때에도 소스 코드 디버깅이 가능하냐의 유무로 나뉩니다. 즉, pdbonly로 하는 경우에는 해당 PDB 파일로는 실행 중에 디버거를 연결하면 어셈블리 코드를 보여주는 모드로만 동작하게 됩니다. 하지만, 일단 문서상으로 그렇다는 것이고 실제로 해보면 pdbonly였어도 정상적으로 디버거 연결이 되고 소스 코드 BP까지 모두 동작합니다. 이에 대한 설명은 다음의 Q&A에서 확인할 수 있는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Should I compile release builds with debug info as “full” or “pdb-only”? ; <a target='tab' href='https://stackoverflow.com/questions/7713514/should-i-compile-release-builds-with-debug-info-as-full-or-pdb-only'>https://stackoverflow.com/questions/7713514/should-i-compile-release-builds-with-debug-info-as-full-or-pdb-only</a> </pre> <br /> .NET 1.x 시절에는 full과 pdbonly의 역할이 달랐지만 .NET 2.0 이후로는 동일하게 되었다고 합니다.<br /> <br /> 그다음 portable 옵션에 대해서는 다음의 문서에서 상세하게 다루고 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Portable PDB ; <a target='tab' href='https://github.com/dotnet/core/blob/main/Documentation/diagnostics/portable_pdb.md'>https://github.com/dotnet/core/blob/main/Documentation/diagnostics/portable_pdb.md</a> </pre> <br /> 위의 문서에도 나오지만, portable PDB에 대한 format은 문서화도 잘 되어 있고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Portable PDB v1.0: Format Specification ; <a target='tab' href='https://github.com/dotnet/runtime/blob/main/docs/design/specs/PortablePdb-Metadata.md'>https://github.com/dotnet/runtime/blob/main/docs/design/specs/PortablePdb-Metadata.md</a> </pre> <br /> 이에 대한 open source까지 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > dotnet/symreader-portable ; <a target='tab' href='https://github.com/dotnet/symreader-portable'>https://github.com/dotnet/symreader-portable</a> </pre> <br /> 무엇보다 cross-platform을 지원하므로 쓰지 않을 이유가 없지만 "<a target='tab' href='https://github.com/dotnet/core/blob/main/Documentation/diagnostics/portable_pdb.md#supported-scenarios'>Portable PDB - Supported scenarios</a>" 문서에 나온 제약이 있다는 점만 유의하시면 됩니다.<br /> <br /> 그중에서 그나마 유의미한 것이 있다면, 4.7.1 이하의 버전에서는 스택 트레이스에 소스 코드 정보가 누락된다는 점이 있습니다.<br /> <br /> 예를 들어, 아래의 소스 코드를 4.7.1로 (portable) 빌드하는 경우,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; class Program { static void Main(string[] args) { Test(); } private static void Test() { throw new NotImplementedException(); } } </pre> <br /> 이렇게 예외 메시지가 출력되지만,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Unhandled Exception: System.NotImplementedException: The method or operation is not implemented. at ConsoleApp1.Program.Test() at ConsoleApp1.Program.Main(String[] args) </pre> <br /> 4.7.2 이상으로 빌드하면 기대했던 소스 파일 및 코드의 라인 정보가 나오게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Unhandled Exception: System.NotImplementedException: The method or operation is not implemented. at ConsoleApp1.Program.Test() in <span style='color: blue; font-weight: bold'>C:\temp\ConsoleApp1\Program.cs:line 12</span> at ConsoleApp1.Program.Main(String[] args) in <span style='color: blue; font-weight: bold'>C:\temp\ConsoleApp1\Program.cs:line 7</span> </pre> <br /> 또 다른 제약으로 MS DIA 기반의 WinDBG에서 지원하지 않는다는 것이 있는데, 실제로 해보면 (심지어 4.7.1 이하로 빌드한 응용 프로그램에 대해서도) 다음과 같이 잘 동작합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:000> <span style='color: blue; font-weight: bold'>!clrstack</span> OS Thread Id: 0x1114 (0) Child SP IP Call Site 00000061ebafeb58 00007ffd68afd759 [HelperMethodFrame: 00000061ebafeb58] 00000061ebafec40 00007ffcf0dd0915 Program.Test() [C:\temp\ConsoleApp1\Program.cs @ 11] 00000061ebafec80 00007ffcf0dd08b2 Program.Main(System.String[]) [C:\temp\ConsoleApp1\Program.cs @ 7] 00000061ebafee98 00007ffd50316923 [GCFrame: 00000061ebafee98] 0:000> <span style='color: blue; font-weight: bold'>!pe</span> Exception object: 0000023d80002e10 Exception type: System.NotImplementedException Message: The method or operation is not implemented. InnerException: <none> StackTrace (generated): SP IP Function 00000061EBAFEC40 00007FFCF0DD0915 ConsoleApp1!Program.Test()+0x45 00000061EBAFEC80 00007FFCF0DD08B2 ConsoleApp1!Program.Main(System.String[])+0x22 0:000> <span style='color: blue; font-weight: bold'>lm</span> 0000023d`f30d0000 0000023d`f30d8000 ConsoleApp1 C (pdb symbols) C:\temp\ConsoleApp1\bin\Debug\ConsoleApp1.pdb </pre> <br /> 마지막 옵션에 해당하는 embedded의 경우 portable과 동일하지만 단지 exe/dll 실행 모듈에 병합된다는 차이점이 있습니다. 또한 (아직인지는 모르겠지만) 현재 WinDBG는 바이너리에 포함된 PDB 정보를 인식하지 못해 소스 코드 정보를 출력하지 못합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0:000> <span style='color: blue; font-weight: bold'>!clrstack</span> OS Thread Id: 0x5104 (0) Child SP IP Call Site 0000008b0aafe918 00007ffd68afd759 [HelperMethodFrame: 0000008b0aafe918] 0000008b0aafea00 00007ffcf0db0925 Program.Test() 0000008b0aafea40 00007ffcf0db08c2 Program.Main(System.String[]) 0000008b0aafec68 00007ffd50316923 [GCFrame: 0000008b0aafec68] </pre> <br /> <hr style='width: 50%' /><br /> <br /> 정리해 보면, .NET Core 응용 프로그램이라면 portable/embedded를 쓰지 않을 이유가 없습니다. 단지 .NET Framework 4.7.1 이하를 지원해야 한다면 기존처럼 full로 권장하고, WinDBG를 고려해야 한다면 embedded보다는 portable이 유용합니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
2037
(왼쪽의 숫자를 입력해야 합니다.)