공용 및 개인 기호

링커에서 전체 크기 .pdb 또는 .dbg 기호 파일을 빌드하는 경우 개인 기호 데이터공용 기호 테이블이라는 두 가지 고유한 정보 컬렉션이 포함됩니다. 이러한 컬렉션은 포함된 항목 목록과 각 항목에 대해 저장하는 정보에 따라 다릅니다.

프라이빗 기호 데이터에는 다음 항목이 포함됩니다.

  • Functions

  • 글로벌 변수

  • 로컬 변수

  • 사용자 정의 구조체, 클래스 및 데이터 형식에 대한 정보

  • 원본 파일의 이름 및 각 이진 명령에 해당하는 해당 파일의 줄 번호

공용 기호 테이블에는 더 적은 수의 항목이 포함됩니다.

  • 함수( 정적으로 선언된 함수 제외)

  • extern으로 지정된 전역 변수(및 여러 개체 파일에 표시되는 다른 전역 변수)

일반적으로 공용 기호 테이블에는 한 원본 파일에서 다른 원본 파일로 액세스할 수 있는 항목이 정확히 포함됩니다. 정적 함수, 단일 원본 파일 내에서만 전역 변수, 지역 변수 등 하나의 개체 파일에만 표시되는 항목은 공용 기호 테이블에 포함되지 않습니다.

이러한 두 데이터 컬렉션은 각 항목에 대해 포함하는 정보와도 다릅니다. 일반적으로 프라이빗 기호 데이터에 포함된 각 항목에 대해 다음 정보가 포함됩니다.

  • 항목의 이름

  • 가상 메모리에 있는 항목의 주소

  • 각 변수, 구조 및 함수의 데이터 형식

  • 각 함수에 대한 매개 변수의 형식 및 이름

  • 각 지역 변수의 범위

  • 각 소스 파일의 각 줄과 연결된 기호

  • 스택에 액세스하는 데 사용되는 각 함수에 대한 FPO(프레임 포인터 누락) 레코드

반면에 공용 기호 테이블에는 포함된 각 항목에 대한 다음 정보만 저장됩니다.

  • 항목의 이름입니다.

  • 모듈의 가상 메모리 공간에 있는 항목의 주소입니다. 함수의 경우 진입점의 주소입니다.

  • 각 함수에 대한 FPO(프레임 포인터 생략) 레코드입니다.

  • 장식이라고 하는 기호 접두사/접미사를 포함할 수 있습니다.

공용 기호 데이터는 두 가지 방법으로 프라이빗 기호 데이터의 하위 집합으로 간주할 수 있습니다. 즉, 항목 목록이 더 짧고 각 항목에 대한 정보가 적습니다. 예를 들어 공용 기호 데이터에는 지역 변수가 전혀 포함되지 않습니다.

각 지역 변수는 주소, 데이터 형식 및 scope 사용하여 프라이빗 기호 데이터에만 포함됩니다. 반면에 함수는 프라이빗 기호 데이터와 공용 기호 테이블에 모두 포함되지만 프라이빗 기호 데이터에는 함수 이름, 주소, FPO 레코드, 입력 매개 변수 이름 및 형식 및 출력 형식이 포함되지만 공용 기호 테이블에는 함수 이름, 주소 및 FPO 레코드만 포함됩니다.

프라이빗 기호 데이터와 공용 기호 테이블 간에는 다른 한 가지 차이점이 있습니다. 공용 기호 테이블의 대부분의 항목에는 접두사, 접미사 또는 둘 다로 데코레이팅된 이름이 있습니다. 이러한 장식은 C 컴파일러, C++ 컴파일러 및 MASM 어셈블러에 의해 추가됩니다. 일반적인 접두사에는 일련의 밑줄 또는 문자열 __imp_ (가져온 함수 지정)이 포함됩니다. 일반적인 접미사에는 하나 이상의 기호( @ )와 주소 또는 기타 식별 문자열이 포함됩니다. 이러한 장식은 함수 이름 또는 전역 변수 이름이 여러 모듈에서 반복될 수 있으므로 링커에서 기호를 구분하는 데 사용됩니다. 이러한 장식은 공용 기호 테이블이 프라이빗 기호 데이터의 하위 집합이라는 일반적인 규칙의 예외입니다.

전체 기호 파일 및 제거된 기호 파일

전체 기호 파일에는 프라이빗 기호 데이터와 공용 기호 테이블이 모두 포함됩니다. 이러한 종류의 파일을 프라이빗 기호 파일이라고도 하지만, 이러한 파일에는 프라이빗 기호와 공용 기호가 모두 포함되어 있기 때문에 이 이름은 오해의 소지가 있습니다.

제거된 기호 파일은 공용 기호 테이블만 포함하는 더 작은 파일입니다. 또는 경우에 따라 공용 기호 테이블의 하위 집합만 포함됩니다. 이 파일을 공용 기호 파일이라고도 합니다.

전체 및 제거된 기호 파일 만들기

Visual Studio를 사용하여 이진 파일을 빌드하는 경우 전체 또는 제거된 기호 파일을 만들 수 있습니다. 제거된 기호를 빌드하는 방법에 대한 자세한 내용은 /PDBSTRIPPED(개인 기호 제거)를 참조하세요.

BinPlace 도구를 사용하여 전체 기호 파일에서 제거된 기호 파일을 만들 수 있습니다. 가장 일반적인 BinPlace 옵션(-a -x -s -n)을 사용하면 제거된 기호 파일이 -s 스위치 다음에 나열된 디렉터리에 배치되고 전체 기호 파일은 -n 스위치 다음에 나열된 디렉터리에 배치됩니다. BinPlace가 기호 파일을 제거하면 파일의 제거된 전체 버전과 동일한 서명 및 기타 식별 정보가 제공됩니다. 이렇게 하면 디버깅에 두 버전 중 하나를 사용할 수 있습니다. BinPlace에 대한 자세한 내용은 BinPlace를 참조하세요.

PDBCopy 도구를 사용하여 프라이빗 기호 데이터를 제거하여 전체 기호 파일에서 제거된 기호 파일을 만들 수 있습니다. PDBCopy는 공용 기호 테이블의 지정된 하위 집합을 제거할 수도 있습니다. 자세한 내용은 PDBCopy를 참조하세요.

SymChk 도구를 사용하여 기호 파일에 프라이빗 기호가 포함되어 있는지 여부를 확인할 수 있습니다. 자세한 내용은 SymChk를 참조하세요.

디버거에서 공용 및 프라이빗 기호 보기

WinDbg, KD 또는 CDB를 사용하여 기호를 볼 수 있습니다. 이러한 디버거 중 하나가 전체 기호 파일에 액세스할 수 있는 경우 프라이빗 기호 데이터에 나열된 정보와 공용 기호 테이블에 나열된 정보가 모두 포함됩니다. 공용 기호 데이터에는 기호 장식이 포함되어 있습니다.

프라이빗 기호에 액세스할 때는 이러한 기호가 공용 기호 테이블에 포함되지 않으므로 항상 프라이빗 기호 데이터가 사용됩니다. 이러한 기호는 장식되지 않습니다.

.symopt(기호 옵션 설정) 명령을 사용하여 디버거에서 퍼블릭 및 프라이빗 기호를 사용하는 방법을 결정하는 기호 옵션을 제어할 수 있습니다. 예를 들어 이 명령은 디버깅 정보를 나타내는 기호를 켭니다.

 .symopt+ 0x80000000

다음 옵션은 디버거에서 공용 및 프라이빗 기호를 사용하는 방법을 변경합니다.

  • SYMOPT_UNDNAME 옵션이 설정되면 공용 기호의 이름이 표시될 때 장식이 포함되지 않습니다. 또한 기호를 검색할 때 장식은 무시됩니다. 이 옵션이 꺼져 있으면 공용 기호를 표시할 때 장식이 표시되고 검색에 장식이 사용됩니다. 개인 기호는 어떤 상황에서도 장식되지 않습니다. 이 옵션은 모든 디버거에서 기본적으로 설정됩니다.

  • SYMOPT_PUBLICS_ONLY 옵션이 설정되면 프라이빗 기호 데이터가 무시되고 공용 기호 테이블만 사용됩니다. 이 옵션은 모든 디버거에서 기본적으로 꺼져 있습니다.

  • SYMOPT_NO_PUBLICS 옵션이 설정되면 공용 기호 테이블이 무시되고 검색 및 기호 정보는 프라이빗 기호 데이터만 사용합니다. 이 옵션은 모든 디버거에서 기본적으로 꺼져 있습니다.

  • SYMOPT_AUTO_PUBLICS 옵션이 설정되고(SYMOPT_PUBLICS_ONLY 및 SYMOPT_NO_PUBLICS 모두 꺼져 있는 경우) 첫 번째 기호 검색이 프라이빗 기호 데이터에서 수행됩니다. 원하는 기호가 있으면 검색이 종료됩니다. 그렇지 않으면 공용 기호 테이블이 검색됩니다. 공용 기호 테이블에는 프라이빗 데이터에 있는 기호의 하위 집합이 포함되어 있으므로 일반적으로 공용 기호 테이블이 무시됩니다.

  • SYMOPT_PUBLICS_ONLY, SYMOPT_NO_PUBLICS 및 SYMOPT_AUTO_PUBLICS 옵션이 모두 해제되면 기호가 필요할 때마다 프라이빗 기호 데이터와 공용 기호 테이블이 모두 검색됩니다. 그러나 두 위치에서 일치 항목이 발견되면 프라이빗 기호 데이터의 일치 항목이 사용됩니다. 따라서 이 instance 동작은 SYMOPT_AUTO_PUBLICS 있을 때와 동일하지만 SYMOPT_AUTO_PUBLICS 사용하면 기호 검색이 약간 더 빠르게 발생할 수 있습니다.

다음은 x 명령(기호 검사) 이 세 번 사용되는 예제입니다. 처음으로 기본 기호 옵션이 사용되므로 개인 기호 데이터에서 정보를 가져옵니다. 여기에는 배열 typingString의 주소, 크기 및 데이터 형식에 대한 정보가 포함됩니다. 다음으로 .symopt+ 4000 명령이 사용되어 디버거가 프라이빗 기호 데이터를 무시합니다. x 명령이 다시 실행되면 공용 기호 테이블이 사용됩니다. 이번에는 typingString에 대한 크기 및 데이터 형식 정보가 없습니다. 마지막으로 .symopt- 2 명령이 사용되어 디버거에 장식이 포함됩니다. 이 마지막 시간에 x 명령을 실행하면 데코레이트된 버전의 함수 이름 (_typingString)이 표시됩니다.

0:000> x /t /d *!*typingstring* 
00434420 char [128] TimeTest!typingString = char [128] ""

0:000> .symopt+ 4000

0:000> x /t /d *!*typingstring* 
00434420 <NoType> TimeTest!typingString = <no type information>

0:000> .symopt- 2

0:000> x /t /d *!*typingstring* 
00434420 <NoType> TimeTest!_typingString = <no type information> 

DBH 도구를 사용하여 공용 및 프라이빗 기호 보기

기호를 보는 또 다른 방법은 DBH 도구를 사용하는 것입니다. 옵션을 사용하여 도움말 옵션을 표시합니다 /? .

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>dbh /?
dbh dbghelp shell
usage: dbh [-n] [-c] [-d] [-?] [-??] [-p] [targetmodule] [command]
       [-n]             display noisy symbol spew
       [-d]             use decorated publics
       [-p:XXXX]        attaches to process ID XXXX
       [-s:SSSS]        set symbol path to SSSS
       [-c]             callbacks return false
       [targetmodule]   load symbols for specified module
       [command]        execute command and exit
       [-?]             display these usage instructions
       [-??]            display detailed usage instructions

Tlist와 같은 도구를 사용하여 프로세스 ID를 나열하고 -p 옵션을 사용하여 기존 프로세스에 연결합니다.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>dbh -p:4308

DBH는 디버거와 동일한 기호 옵션을 사용합니다. 디버거와 마찬가지로 DBH는 기본적으로 SYMOPT_PUBLICS_ONLY 두고 SYMOPT_NO_PUBLICS 해제하고 기본적으로 SYMOPT_UNDNAME 켜고 SYMOPT_AUTO_PUBLICS . 이러한 기본값은 명령줄 옵션 또는 DBH 명령으로 재정의할 수 있습니다.

다음은 DBH 명령 추가기 414fe0 을 세 번 사용하는 예제입니다. 처음으로 기본 기호 옵션이 사용되므로 개인 기호 데이터에서 정보를 가져옵니다. 여기에는 함수 fgets의 주소, 크기 및 데이터 형식에 대한 정보가 포함됩니다. 다음으로 symopt +4000 명령이 사용되어 DBH가 프라이빗 기호 데이터를 무시합니다. addr 414fe0이 다시 실행되면 공용 기호 테이블이 사용됩니다. 이번에는 함수 fgets에 대한 크기 및 데이터 형식 정보가 없습니다. 마지막으로 Symopt -2 명령이 사용되어 DBH에 장식이 포함됩니다. 이 마지막 시간에 addr 414fe0 을 실행하면 데코레이트된 버전의 함수 이름 (_fgets)이 표시됩니다.

pid:4308 mod:TimeTest[400000]: addr 414fe0

fgets
   name : fgets
   addr :   414fe0
   size : 113
  flags : 0
   type : 7e
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagFunction (5)
  index : 7d

pid:4308 mod:TimeTest[400000]: symopt +4000

Symbol Options: 0x10c13
Symbol Options: 0x14c13

pid:4308 mod:TimeTest[400000]: addr 414fe0

fgets
   name : fgets
   addr :   414fe0
   size : 0
  flags : 0
   type : 0
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagPublicSymbol (a)
  index : 7f

pid:4308 mod:TimeTest[400000]: symopt -2

Symbol Options: 0x14c13
Symbol Options: 0x14c11

pid:4308 mod:TimeTest[400000]: addr 414fe0

_fgets
   name : _fgets
   addr :   414fe0
   size : 0
  flags : 0
   type : 0
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagPublicSymbol (a)
  index : 7f 

추가 정보

기호에 대한 자세한 내용은 기호 구문 및 기호 일치, 기호 옵션, 기호 상태 약어지연 기호 로드를 참조하세요.