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


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

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

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

  • Функции

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

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

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

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

Таблица открытых символов содержит меньше элементов:

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

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

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

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

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

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

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

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

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

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

  • Записи пропуска указателя кадра (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 (Set Symbol Options) можно использовать для управления параметрами символов , которые определяют, как открытые и закрытые символы используются отладчиком. Например, эта команда включает символы для отладки информации.

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

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

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