VS 디버거 '마법의 이름'에 대해 배울 수있는 곳


110

Reflector를 사용해 본 적이 있다면 C # 컴파일러가 디버거에서 '특별한'표시를해야하는 유형, 메서드, 필드 및 지역 변수를 생성한다는 것을 알 수 있습니다. 예를 들어 'CS $'로 시작하는 지역 변수는 사용자에게 표시되지 않습니다. 익명 메서드의 클로저 유형, 자동 속성의 지원 필드 등에 대한 다른 특수 명명 규칙이 있습니다.

내 질문 : 이러한 명명 규칙에 대해 어디서 배울 수 있습니까? 누구든지 문서에 대해 알고 있습니까?

내 목표는 PostSharp 2.0이 동일한 규칙을 사용하도록 만드는 것입니다.

답변:


209

이는 컴파일러의 문서화되지 않은 구현 세부 사항이며 언제든지 변경 될 수 있습니다. (업데이트 : GeneratedNames.cs 현재 세부 정보는 C # 소스를 참조하십시오. 아래 설명은 다소 오래되었습니다.)

그러나 나는 좋은 사람이기 때문에 여기에 몇 가지 세부 사항이 있습니다.

옵티마이 저가 제거하는 사용되지 않은 지역 변수가있는 경우, 어쨌든 PDB로 디버그 정보를 내 보냅니다. __Deleted$이러한 변수에 접미사 를 붙여 디버거가 해당 변수가 소스 코드에 있지만 바이너리로 표시되지 않음을 알 수 있도록했습니다.

컴파일러에 의해 할당 된 임시 변수 슬롯에는 CS $ X $ Y 패턴으로 이름이 지정됩니다. 여기서 X는 "임시 종류"이고 Y는 지금까지 할당 된 임시의 수입니다. 임시 종류는 다음과 같습니다.

0 --> short lived temporaries
1 --> return value temporaries
2 --> temporaries generated for lock statements
3 --> temporaries generated for using statements
4 --> durable temporaries
5 --> the result of get enumerator in a foreach
6 --> the array storage in a foreach
7 --> the array index storage in a foreach.  

8에서 264 사이의 임시 종류는 다차원 배열을위한 추가 배열 인덱스 저장소입니다.

264 이상의 임시 종류는 문자열을 고정하는 고정 문과 관련된 임시에 사용됩니다.

다음에 대해 특수 컴파일러 생성 이름이 생성됩니다.

1 --> the iterator state ("state")
2 --> the value of current in an iterator ("current")
3 --> a saved parameter in an iterator
4 --> a hoisted 'this' in an iterator ("this")
5 --> a hoisted local in an iterator
6 --> the hoisted locals from an outer scope
7 --> a hoisted wrapped value ("wrap")
8 --> the closure class instance ("locals")
9 --> the cached delegate instance ("CachedAnonymousMethodDelegate")
a --> the iterator instance ("iterator")
b --> an anonymous method
c --> anonymous method closure class ("DisplayClass")
d --> iterator class
e --> fixed buffer struct ("FixedBuffer")
f --> anonymous type ("AnonymousType")
g --> initializer local ("initLocal")
h --> query expression temporary ("TransparentIdentifier")
i --> anonymous type field ("Field")
j --> anonymous type type parameter ("TPar")
k --> auto prop field ("BackingField")
l --> iterator thread id
m --> iterator finally ("Finally")
n --> fabricated method ("FabricatedMethod")
o --> dynamic container class ("SiteContainer")
p --> dynamic call site ("Site")
q --> dynamic delegate ("SiteDelegate")
r --> com ref call local ("ComRefCallLocal")
s --> lock taken local ("LockTaken")

마법의 이름을 생성하는 패턴은 다음 P<N>C__SI과 같습니다.

  • P는 캐시 된 대리자 및 표시 클래스 인스턴스의 경우 CS $이고 그렇지 않으면 비어 있습니다.
  • N은 사물과 관련된 원래 이름입니다 (있는 경우).
  • C는 위에 나열된 문자 1부터 s까지입니다.
  • S는 설명 접미사 ( "current", "state"등)이므로 메타 데이터를 읽을 때 위의 표를 기억할 필요가 없습니다.
  • 나는 선택적 고유 번호입니다.

2
감사합니다! PostSharp 클로저 클래스가 C # 컴파일러가 생성하는 것처럼 멋지게 작동하도록 만들 수 있는지 살펴 보겠습니다!
Gael Fraiteur

7
@SLaks : 일시적인 단기의 반대입니다. Durable 임시는 본질적으로 이름이없는 지역 변수입니다. 그들은 스택 프레임의 수명 동안 존재하는 스택의 특정 위치를 가지고 있습니다. 수명이 짧은 임시 파일은 스토리지가 필요할 때 스택에 푸시 된 다음 더 이상 필요하지 않을 때 팝업됩니다. 내구성있는 임시 파일은 디버그하기가 훨씬 더 쉽지만 임시 파일의 수명을 훨씬 더 길게 만들 수 있습니다. 최적화가 꺼져있을 때 내구성있는 임시를 생성합니다.
Eric Lippert

클로저 클래스와 비슷한 개념이 있지만 매개 변수를 필드로 끌어 올리는 대신 지역 변수로 사용합니다. 이것은 매개 변수에 대해 잘 작동하지만 'this'가 'ldarg.0'이 아니라 인덱스 4를 가진 지역 변수라고 디버거에 알리는 방법은 무엇입니까? 마법의 이름이 있습니까?
Gael Fraiteur 2010

23
@Eric-이 응답을 C # 5.0 (async / await)에서 생성 된 이름으로 업데이트 할 수 있습니까? 나는 몇 가지 새로운 접두사를 :) 본 적이
가엘 Fraiteur
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.