设置 visual studio c++ 调试器以支持从内存加载的模块的符号
Setting up visual studio c++ debugger to support symbols for modules loaded from memory
我正在使用以下 code 将内存中的 DLL 加载到另一个 运行 可执行文件中。使用常用方法调试以下模块将无法工作,因为调试器无法找到适当的 PDB 文件,更不用说让它知道 DLL 实际上已加载到进程中。我设法以某种方式设置它与 windbg 一起工作:
- 使用
.reload [DLLLocationInMemory]=0x10000000,[DllSizeInMemory]a48194
指定内存中模块所在的调试器及其长度
- 正在重新安排符号服务器
.sympath SRV*C:\Symbols\MS\*http://msdl.microsoft.com/download/symbols;c:\mySpecialSymbolsDir
- 运行演出
每次调试迭代都这样做很烦人,我想知道是否可以使用 visual studio 的调试来完成类似的事情 window(尤其是步骤 #1)。
您可以运行 .imgscan /l
找到内存中的所有模块和 de-facto .reload
它们。
(这个 meta-command 基本上做的是在所有 page-aligned 地址上搜索“MZ”。对于它找到的每个“MZ”,它会尝试将从此地址开始的数据解释为DOS_IMAGE_HEADERS
结构,获取结构的 e_lfanew
字段,转到它指向的位置并假设那里有一个 PE header (NT_IMAGE_HEADER
)。然后它转到 [= PE IMAGE_OPTIONAL_HEADER
部分的 15=] 字段 header。然后它调用 .reload ModName=AddressOfFoundMZ,SizeOfImage
。我不确定你是否会为加载的模块获得一个有意义的名称你加载它们的方式。)
您的符号路径应该是工作区的一部分或在环境变量 _NT_SYMBOL_PATH
中设置(或者按照 Thomas 的建议为 WinDbg 使用 command-line 参数)。无论您是调试正常加载的 DLL 还是以这种方式加载,也无论您使用 Visual Studio 还是 WinDbg.
,都是如此。
我非常怀疑这在 Visual Studio 中是否可行。我知道 Visual Studio 中的模块 Windows 中没有这样的选项,并且鉴于 Visual Studio by design does not allow loading mismatched symbols 我看不到它允许您声明 "well, you see this memory region - assume that's a DLL there...";这正是 WinDbg 的用途。
虽然您的标题说 "Visual Studio",但在您的问题和评论中,您提到如果该过程可以自动化,WinDbg 解决方案也会有所帮助。所以这是一个 WinDbg 答案。
符号路径
WinDbg 知道工作区的概念。只有阅读和练习才能得到它 Uncovering how Workspaces work with WinDbg [MSDN blogs]。了解它们的工作原理后,设置基础工作区以包含您最喜欢的符号路径。
一旦您对工作区感到满意,请为 WinDbg 创建一个 link 以包含 -Q
:抑制烦人的 "Save workspace?" 问题。
作为替代方案,您可以使用 -y <SymbolPath>
命令行开关传递符号路径。
或者,如果命令太长,请使用更短、更全面的形式
.sympath c:\mySpecialSymbolsDir
.symfix+ C:\Symbols\MS\
运行 启动时的命令
要运行 WinDbg 启动时的命令,请使用-c "<command>"
。这应该例如.reload
没问题。如果您想 运行 许多命令或复杂命令(尤其是涉及引号时),请查看 Run script file [MSDN].
其他
根据您是在进行实时调试还是故障转储分析,您可能希望使用更多 WinDbg command line options [MSDN]。
可能对您的情况有用的东西:
-pn <name>: Debug a process by name
-<executable>: Start the executable instead of attaching.
-z <dump>: Debug a dump file
-srcpath <path>: Path to your sources
我正在使用以下 code 将内存中的 DLL 加载到另一个 运行 可执行文件中。使用常用方法调试以下模块将无法工作,因为调试器无法找到适当的 PDB 文件,更不用说让它知道 DLL 实际上已加载到进程中。我设法以某种方式设置它与 windbg 一起工作:
- 使用
.reload [DLLLocationInMemory]=0x10000000,[DllSizeInMemory]a48194
指定内存中模块所在的调试器及其长度
- 正在重新安排符号服务器
.sympath SRV*C:\Symbols\MS\*http://msdl.microsoft.com/download/symbols;c:\mySpecialSymbolsDir
- 运行演出
每次调试迭代都这样做很烦人,我想知道是否可以使用 visual studio 的调试来完成类似的事情 window(尤其是步骤 #1)。
您可以运行 .imgscan /l
找到内存中的所有模块和 de-facto .reload
它们。
(这个 meta-command 基本上做的是在所有 page-aligned 地址上搜索“MZ”。对于它找到的每个“MZ”,它会尝试将从此地址开始的数据解释为DOS_IMAGE_HEADERS
结构,获取结构的 e_lfanew
字段,转到它指向的位置并假设那里有一个 PE header (NT_IMAGE_HEADER
)。然后它转到 [= PE IMAGE_OPTIONAL_HEADER
部分的 15=] 字段 header。然后它调用 .reload ModName=AddressOfFoundMZ,SizeOfImage
。我不确定你是否会为加载的模块获得一个有意义的名称你加载它们的方式。)
您的符号路径应该是工作区的一部分或在环境变量 _NT_SYMBOL_PATH
中设置(或者按照 Thomas 的建议为 WinDbg 使用 command-line 参数)。无论您是调试正常加载的 DLL 还是以这种方式加载,也无论您使用 Visual Studio 还是 WinDbg.
我非常怀疑这在 Visual Studio 中是否可行。我知道 Visual Studio 中的模块 Windows 中没有这样的选项,并且鉴于 Visual Studio by design does not allow loading mismatched symbols 我看不到它允许您声明 "well, you see this memory region - assume that's a DLL there...";这正是 WinDbg 的用途。
虽然您的标题说 "Visual Studio",但在您的问题和评论中,您提到如果该过程可以自动化,WinDbg 解决方案也会有所帮助。所以这是一个 WinDbg 答案。
符号路径
WinDbg 知道工作区的概念。只有阅读和练习才能得到它 Uncovering how Workspaces work with WinDbg [MSDN blogs]。了解它们的工作原理后,设置基础工作区以包含您最喜欢的符号路径。
一旦您对工作区感到满意,请为 WinDbg 创建一个 link 以包含 -Q
:抑制烦人的 "Save workspace?" 问题。
作为替代方案,您可以使用 -y <SymbolPath>
命令行开关传递符号路径。
或者,如果命令太长,请使用更短、更全面的形式
.sympath c:\mySpecialSymbolsDir
.symfix+ C:\Symbols\MS\
运行 启动时的命令
要运行 WinDbg 启动时的命令,请使用-c "<command>"
。这应该例如.reload
没问题。如果您想 运行 许多命令或复杂命令(尤其是涉及引号时),请查看 Run script file [MSDN].
其他
根据您是在进行实时调试还是故障转储分析,您可能希望使用更多 WinDbg command line options [MSDN]。
可能对您的情况有用的东西:
-pn <name>: Debug a process by name
-<executable>: Start the executable instead of attaching.
-z <dump>: Debug a dump file
-srcpath <path>: Path to your sources