Поделиться через


Открытые и частные символы

Когда создается полноразмерный символьный файл PDB или DBG с помощью компоновщика, он содержит две различные коллекции информации: закрытые символьные данные и общедоступную таблицу символов. Эти коллекции отличаются в списке элементов, которые они содержат, и сведения, которые они хранят о каждом элементе.

Данные частного символа включают следующие элементы:

  • Функции

  • Глобальные переменные

  • Локальные переменные

  • Сведения о определяемых пользователем структурах, классах и типах данных

  • Имя исходного файла и номер строки в этом файле, соответствующие каждой двоичной инструкции.

Общедоступная таблица символов содержит меньше элементов:

  • Функции (за исключением функций, объявленных статическими)

  • Глобальные переменные, указанные как экстерн (и любые другие глобальные переменные, видимые в нескольких файлах объектов)

Как правило, общедоступная таблица символов содержит именно те элементы, которые доступны из одного исходного файла в другой. Элементы, видимые только в одном файле объекта, например статические функции, переменные, которые являются глобальными только в одном исходном файле, а локальные переменные не включены в таблицу открытых символов.

Эти две коллекции данных также отличаются в том, какие сведения они включают для каждого элемента. Следующие сведения обычно включаются для каждого элемента, содержащегося в данных частного символа:

  • Имя элемента

  • Адрес элемента в виртуальной памяти

  • Тип данных каждой переменной, структуры и функции

  • Типы и имена параметров для каждой функции

  • Область каждой локальной переменной

  • Символы, связанные с каждой строкой в каждом исходном файле

  • Записи опущений указателя кадров (FPO) для каждой функции, используемой для доступа к стеку

С другой стороны, общедоступная таблица символов хранит только следующие сведения о каждом элементе, включенном в него:

  • Наименование номенклатуры.

  • Адрес элемента в пространстве виртуальной памяти модуля. Для функции это адрес точки входа.

  • Записи об опущениях индикатора фрейма (FPO) для каждой функции.

  • Может включать префикс или суффиксы символов, называемые украшениями.

Данные открытого символа можно рассматривать как подмножество данных частного символа двумя способами: он содержит более короткий список элементов, а также содержит меньше сведений о каждом элементе. Например, данные открытого символа не включают локальные переменные вообще.

Каждая локальная переменная включается только в данные приватных символов с её адресом, типом данных и областью. Функции, с другой стороны, включаются как в данные частного символа, так и в таблицу открытых символов, но в то время как данные частного символа включают имя функции, адрес, записи 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 отключены, каждый раз, когда это необходимо, выполняется поиск и закрытых символов, и публичной таблицы символов. Однако при обнаружении совпадений в обоих местах используется совпадение в данных с закрытыми символами. Таким образом, поведение в этом случае такое же, как когда SYMOPT_AUTO_PUBLICS включен, за исключением того, что использование SYMOPT_AUTO_PUBLICS может привести к немного более быстрому поиску символов.

Ниже приведен пример, в котором используется команда x (проверка символов) три раза. При первом использовании используются параметры символов по умолчанию и поэтому данные взяты из данных частного символа. Обратите внимание, что это включает сведения об адресе, размере и типе данных массива typeingString. Затем используется команда .symopt+ 4000, в результате чего отладчик пропускает данные приватных символов. При повторном выполнении команды x используется общедоступная таблица символов; На этот раз нет сведений о размере и типе данных для typeingString. Наконец, используется команда .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, чтобы перечислить идентификаторы процессов и параметр -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 addr 414fe0 три раза. При первом использовании используются параметры символов по умолчанию и поэтому данные взяты из данных частного символа. Обратите внимание, что это включает сведения об адресе, размере и типе данных функции fgets. Затем используется команда symopt +4000, что приводит к тому, что DBH игнорирует данные закрытых символов. При повторном запуске addr 414fe0 используется общедоступная таблица символов; На этот раз нет сведений о размере и типе данных для функции fgets. Наконец, используется команда symopt -2, которая заставляет DBH включать декорации. Когда надстройка 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 

Дополнительные сведения

Дополнительные сведения о символах см. в разделе "Синтаксис символов" и "Сопоставление символов", " Параметры символов", "Аббревиация состояния символов" и "Отложенная загрузка символов".