源服务器
源服务器使客户端能够检索用于生成应用程序的源文件的确切版本。 由于模块的源代码可以在版本之间和几年内发生更改,因此,在生成相关模块版本时,查看源代码非常重要。
源服务器从源代码管理中检索相应的文件。 若要使用源服务器,应用程序必须已编制源索引。
源索引
源索引系统是可执行文件和 Perl 脚本的集合。 Perl 脚本需要 Perl 5.6 或更高版本。
通常,二进制文件是在生成应用程序后在生成过程中编制索引的。 源服务器所需的信息存储在 PDB 文件中。
源服务器当前附带的脚本应适用于以下源代码管理系统。
- Team Foundation Server
- Perforce
- Visual SourceSafe
- CVS
- 颠覆
还可以创建自定义脚本,为其他源代码管理系统为代码编制索引。
下表列出了源服务器工具。
工具 | 描述 |
---|---|
Srcsrv.ini | 此文件是所有源代码管理服务器的主列表。 每个条目采用以下格式:MYSERVER=serverinfo 使用 Perforce 时,服务器信息由服务器的完整网络路径组成,后跟冒号,后跟它使用的端口号。 例如: MYSERVER=machine.corp.company.com:1666 可以在运行调试器的计算机上安装此文件。 源服务器启动时,它会查看值 Srcsrv.ini;这些值将替代 PDB 文件中包含的信息。 这使用户可以在调试时配置调试器以使用备用源代码管理服务器。 有关详细信息,请参阅示例 Srcsrv.ini 随源服务器工具一起安装。 |
Ssindex.cmd | 此脚本生成签入源代码管理的文件列表以及每个文件的版本信息。 它将此信息的子集存储在生成应用程序时生成的 .pdb 文件中。 该脚本使用以下 Perl 模块之一来与源代码管理进行交互:P4.pm(Perforce)或 Vss.pm(Visual Source Safe)。有关详细信息,请使用 -? 或-?? (详细帮助)选项或检查脚本。 |
Srctool.exe | 此实用工具列出在 .pdb 文件中编制索引的所有文件。 对于每个文件,它将列出文件的完整路径、源代码管理服务器和版本号。 可以使用此信息在不使用源服务器的情况下检索文件。有关详细信息,请使用 /? 选择。 |
Pdbstr.exe | 索引脚本使用此实用工具将版本控制信息插入目标 .pdb 文件的“srcsrv”备用流中。 它还可以从 .pdb 文件读取任何流。 可以使用此信息来验证索引脚本是否正常工作。有关详细信息,请使用 /? 选择。 |
检索源文件
DbgHelp API 通过 SymGetSourceFile 函数提供对源服务器功能的访问权限。 若要检索要检索的源文件的名称,请调用 SymEnumSourceFiles 或 SymGetLineFromAddr64 函数。
将源服务器与调试器配合使用
若要将源服务器与 WinDbg、KD、NTSD 或 CDB 配合使用,请确保已安装最新版本的 Windows 调试工具包(版本 6.3 或更高版本)。 然后,在 .srcpath 命令中包含 srv*,如下所示:
.srcpath srv*;c:\mysource
请注意,此示例还包括传统的源路径。 如果调试器无法从源服务器检索文件,它将搜索指定的路径。
如果源服务器检索源文件,调试会话结束后,它将保留在硬盘驱动器上。 源文件存储在 Windows 安装目录调试工具的 src 子目录中。
源服务器数据块
源服务器依赖于 PDB 文件中的两个数据块。
- 源文件列表。 生成模块会自动创建用于生成模块的源文件的完全限定路径列表。
- 数据块。 为源编制索引,如前所述,将备用流添加到名为“srcsrv”的 PDB 文件。 插入此数据的脚本依赖于正在使用的特定生成过程和源代码管理系统。
在语言规范版本 1 中,数据块分为三个部分:ini、变量和源文件。 它具有以下语法。
SRCSRV: ini ------------------------------------------------
VERSION=1
VERCTRL=<source_control_str>
DATETIME=<date_time_str>
SRCSRV: variables ------------------------------------------
SRCSRVTRG=%sdtrg%
SRCSRVCMD=%sdcmd%
SRCSRVENV=var1=string1\bvar2=string2
DEPOT=//depot
SDCMD=sd.exe -p %fnvar%(%var2%) print -o %srcsrvtrg% -q %depot%/%var3%#%var4%
SDTRG=%targ%\%var2%\%fnbksl%(%var3%)\%var4%\%fnfile%(%var1%)
WIN_SDKTOOLS= sserver.microsoft.com:4444
SRCSRV: source files ---------------------------------------
<path1>*<var2>*<var3>*<var4>
<path2>*<var2>*<var3>*<var4>
<path3>*<var2>*<var3>*<var4>
<path4>*<var2>*<var3>*<var4>
SRCSRV: end ------------------------------------------------
除用百分号括住的文本(%)外,所有文本均按字面解释。 括在百分号中的文本被视为以递归方式解析的变量名称,除非它是以下函数之一:
-
%fnvar%()
-
参数文本应括在百分比符号中,并被视为要展开的变量。
-
%fnbksl%()
-
参数文本中的所有正斜杠(/)都应替换为后斜杠(\)。
-
%fnfile%()
-
参数文本中的所有路径信息都应去除,只保留文件名。
ini 节包含描述要求的变量。 索引脚本可以将任意数量的变量添加到此部分。 下面是示例:
-
版本
-
语言规范版本。 此变量是必需的。
-
VERCTL
-
描述源代码管理产品的字符串。 此变量是可选的。
-
DATETIME
-
一个字符串,指示处理 PDB 文件的日期和时间。 此变量是可选的。
variables 节包含描述如何从源代码管理中提取文件的变量。 它还可用于将常用文本定义为变量,以减少数据块的大小。
-
SRCSRVTRG
-
介绍如何为提取的文件生成目标路径。 这是必需的变量。
-
SRCSRVCMD
-
介绍如何生成命令以从源代码管理中提取文件。 这包括可执行文件的名称及其命令行参数。 这是必需的变量。
-
SRCSRVENV
-
列出在文件提取过程中要创建的环境变量的字符串。 用后空字符(\b)分隔多个条目。 这是一个可选变量。
源文件部分包含已编制索引的每个源文件的条目。 每行的内容被解释为名为 VAR1、VAR2、VAR3 等的变量,直到 VAR10。 变量由星号分隔。 VAR1 必须指定源文件的完全限定路径,如 PDB 文件中的其他位置列出。 例如,以下行:
c:\proj\src\file.cpp*TOOLS_PRJ*tools/mytool/src/file.cpp*3
解释如下:
VAR1=c:\proj\src\file.cpp
VAR2=TOOLS_PRJ
VAR3=tools/mytool/src/file.cpp
VAR4=3
在此示例中,VAR4 是版本号。 但是,大多数源代码管理系统都支持以某种方式标记文件,以便可以还原给定版本的源状态。 因此,可以替代使用生成标签。 可以修改示例数据块以包含如下所示的变量:
LABEL=BUILD47
然后,假设源代码管理系统使用 at sign (@) 来指示标签,可以按如下所示修改 SRCSRVCMD 变量:
sd.exe -p %fnvar%(%var2%) 打印 -o %srcsrvtrg% -q %depot%/%var3%@%label%
源服务器的工作原理
源服务器客户端在 Symsrv.dll中实现。 客户端不会直接从 PDB 文件提取信息;它使用符号处理程序,例如在 Dbghelp.dll中实现的符号处理程序。 它本质上是递归变量替换引擎,它创建一个命令行,可用于从源代码管理系统中提取正确的源文件。 代码不应直接调用 Symsrv.dll。 若要将其功能集成到应用程序中,请使用 SymGetSourceFile 函数。
源服务器的第一个版本如下所示。 将来的版本可能会更改此行为。
- 客户端调用 SrcSrvInit 函数,并将目标路径用作所有源文件提取的基础。 它将此路径存储在 TARG 变量中。
- 当加载模块 PDB 时,客户端将从 PDB 中提取 Srcsrv 流,并调用 SrcSrvLoadModule 函数将数据块传递给源服务器。
- 当 Dbghelp 检索源文件时,客户端调用 SrcSrvGetFile 函数从源代码管理检索源文件。
- 源服务器在数据块中搜索源文件条目,以获取与请求的文件匹配的条目。 它将 VAR1 填充到 VARn,其中包含源文件条目的内容。 接下来,它将使用 VAR1 将 SRCSRVTRG 变量扩展到 VARn。 如果文件已位于此位置,则会将位置返回到调用方。 否则,它会扩展 SRCSRVCMD 变量以生成从源代码管理检索文件所需的命令,并将其复制到目标位置。 最后,它执行此命令。
创建源代码管理提供程序模块
源服务器包括 Perforce(p4.pm)和 Visual Source Safe(vss.pm)的提供程序模块。 若要创建自己的提供程序模块,必须实现以下接口集。
-
$module::SimpleUsage()
-
目的:向 STDOUT 显示简单的模块使用情况信息。
参数:无
返回值:无
-
$module::VerboseUsage()
-
目的:向 STDOUT 显示深入模块使用情况信息。
参数:无
返回值:无
-
$objref = $module::new(@CommandArguments)
-
目的:初始化提供程序模块的实例。
参数:SSIndex.cmd未识别为常规参数的所有 @ARGV 参数。
返回值:可在后续作中使用的引用。
-
$objref->GatherFileInformation($SourcePath, $ServerHashReference)
-
目的:使模块能够收集由 $SourcePath 参数指定的目录所需的源索引信息。 模块不应假定每个对象实例只调用一次此条目,因为SSIndex.cmd可能会针对不同的路径多次调用它。
参数:(1) 包含要编制索引的源的本地目录。 (2) 对包含指定 Srcsrv.ini 文件中所有条目的哈希的引用。
返回值:无
-
($VariableHashReference, $FileEntry) = $objref->GetFileInfo($LocalFile)
-
目的:提供从源代码管理系统中提取单个特定文件所需的信息。
参数:完全限定的文件名
返回值:(1) 解释返回$FileEntry所需的变量的哈希引用。 SSIndex.cmd为单个调试文件使用的每个源文件缓存这些变量,以减少写入源索引流的信息量。 (2) 要写入源索引流的文件条目,以允许 SrcSrv.dll 从源代码管理中提取此文件。 此行的确切格式特定于源代码管理系统。
-
$TextString = $objref->LongName()
-
目的:提供描述性字符串来标识最终用户的源代码管理提供程序。
参数:无
返回值:源代码管理系统的描述性名称。
-
@StreamVariableLines = $objref->SourceStreamVariables()
-
目的:使源代码管理提供程序能够将特定于源代码的变量添加到每个调试文件的源流中。 示例模块使用此方法编写所需的EXTRACT_CMD和EXTRACT_TARGET变量。
参数:无
返回值:源流变量的条目列表。