C++ 为什么使用Windbg的pdb文件的校验和失败?
我在VS2015中创建了一个模拟崩溃的简单控制台演示应用程序。我使用windbg运行可执行文件以调试它,以用于演示目的。应用程序按预期运行和崩溃 但这就是windbg的怪异之处 当我在同一台机器上构建调用堆栈函数时,我看不到它对应的代码。调用堆栈旁边的源代码行不在源代码所在的位置,它几乎没有引用我的示例代码(单个main.cpp文件) 当我运行C++ 为什么使用Windbg的pdb文件的校验和失败?,c++,visual-studio-2015,windbg,C++,Visual Studio 2015,Windbg,我在VS2015中创建了一个模拟崩溃的简单控制台演示应用程序。我使用windbg运行可执行文件以调试它,以用于演示目的。应用程序按预期运行和崩溃 但这就是windbg的怪异之处 当我在同一台机器上构建调用堆栈函数时,我看不到它对应的代码。调用堆栈旁边的源代码行不在源代码所在的位置,它几乎没有引用我的示例代码(单个main.cpp文件) 当我运行lm Project1.exe时,它不理解Project1.exe 0:000> lm Project1.exe Unknown option 'P
lm Project1.exe
时,它不理解Project1.exe
0:000> lm Project1.exe
Unknown option 'P'
Unknown option 'r'
Unknown option 'j'
^ Syntax error in 'lm Project1.exe'
更有趣的是,当我运行lm
命令时,它会在Project1
模块旁边显示C
,这意味着校验和不匹配,但为什么呢?它是在同一台机器上构建的,符号文件应该100%匹配,但显然不匹配
0:000> lm
start end module name
00e30000 00e51000 Project1 C (pdb symbols) C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\sym\Project1.pdb\73D98E9A3EDD4D4D8AE90DF76040737D1\Project1.pdb
0f000000 0f006000 detoured (deferred)
0f3d0000 0f546000 ucrtbased (private pdb symbols) C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\sym\ucrtbased.pdb\D9FF3B7405474C158B4E3C2FBCC108362\ucrtbased.pdb
实际上,它甚至没有对主Project1.exe
模块说private pdb symbols
,就像它找不到符号一样
校验和问题也反映在k
命令中
0:000> k
# ChildEBP RetAddr
00 002df984 77a18e12 ntdll!NtTerminateProcess+0x12
01 002df9a0 756c79c4 ntdll!RtlExitUserProcess+0x85
02 002df9b4 608c91b8 kernel32!ExitProcessStub+0x12
03 002df9c0 608c916c ucrtbased!exit_or_terminate_process+0x38 [d:\rs1\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp @ 130]
04 002df9dc 608c9452 ucrtbased!common_exit+0x5c [d:\rs1\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp @ 265]
*** WARNING: Unable to verify checksum for Project1.exe
05 002df9f0 012a2348 ucrtbased!exit+0x12 [d:\rs1\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp @ 278]
06 002dfa4c 012a21cd Project1!__scrt_common_main_seh+0x168 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 262]
07 002dfa54 012a24e8 Project1!__scrt_common_main+0xd [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 296]
08 002dfa5c 756c336a Project1!wmainCRTStartup+0x8 [f:\dd\vctools\crt\vcstartup\src\startup\exe_wmain.cpp @ 17]
09 002dfa68 779f9902 kernel32!BaseThreadInitThunk+0xe
0a 002dfaa8 779f98d5 ntdll!__RtlUserThreadStart+0x70
0b 002dfac0 00000000 ntdll!_RtlUserThreadStart+0x1b
当这个简单的项目建立在同一台机器上时,为什么windbg不能找到东西,也不能产生有意义的结果呢
当我运行lm Project1.exe时,它不理解Project1.exe
0:000> lm Project1.exe
Unknown option 'P'
Unknown option 'r'
Unknown option 'j'
^ Syntax error in 'lm Project1.exe'
lm Project1.exe
命令失败有两个原因:
Project1
,而不是Project1.exe
lm m Project1
私有pdb符号
,就像它找不到符号一样
我认为这对于发布版本来说是正常的。私人信息被剥夺
它在Project1模块旁边显示C,这意味着校验和不匹配
关于校验和的C,帮助说明:
The checksum is missing, not accessible, or equal to zero.
IMHO,对于PDB的识别,时间戳足够可靠,不需要校验和。可以使用检查可执行文件是否与符号匹配
在调试和发布版本中,我得到了C#程序的C警告,但我没有问题
你在评论中说:
我的系统上甚至没有f:\dd文件夹
这可能是由链接器生成的。您使用静态链接,在您的可执行文件中嵌入了一些C++运行时的东西,其中源由微软编译。
还有人说:
它正在从一个不寻常的目录加载Project1符号 没错,但是应用程序的符号可以存储在符号存储中,具体取决于符号路径配置 看。你的情况应该是这样的
.sympath C:\path\to\your\symbols
.symfix+ C:\microsoft\symbols
.reload
为什么windbg找不到东西
你希望找到什么
难道没有产生有意义的结果吗
输出的哪一部分对您没有意义?您需要在项目中设置/release开关,以便将chksum设置为调试buulds的默认值为nochksum
发布buikds的默认值是setchksum 要将lm与modulename一起使用,您需要-m开关 喜欢。Lm-m专业版*
您可以对modname使用通配符。Windbg将显示与模式匹配的所有模块 这个。F:\dd路径来自crt源。它们位于vs src文件夹中。因为它们是硬编码路径 您可能需要将src文件夹复制到本地计算机中的确切目录结构中 即md f:\dd……。。并将整个src文件夹复制到该路径。Windbg将挑选资源 如果。您编译、调试或发布的pdb不会被剥离,除非您使用pdbcopy或binplace剥离私有符号,否则它们仍然是私有pdb 堆栈显示terminateprocess。这意味着。它已超过您的用户代码,您可能需要手动打开源文件。使用。Lsa-ls命令
从手机输入,以便我可以进一步编辑此内容以添加信息您说“当我运行lmi Project1.exe时”,但您显示的是
lm Project1.exe
。请注意,lmi
是一个扩展命令。@RichardCriten谢谢,这是打字错误,我已修复。它正在从一个不寻常的目录加载Project1符号,我希望它从build目录加载它们。自生成以来已复制了大约个文件。它看起来像是从符号缓存中加载它们,所以选择了旧版本。如果是,请尝试从符号缓存中删除pdb文件。@RichardCriten生成后不会复制项目或其任何文件。我还从缓存中删除了pdb文件,但它没有改变任何东西。是的,它确实指向奇怪的路径,我的系统上甚至没有f:\dd
文件夹。谢谢,这两个答案都很好。原来我把lm
和搞混了!lmi
,后者采用完整的模块名,扩展名为!lmi Project1.exe
。这个版本是调试版本。它确实是调试版本,但我注意到当我发布版本时C仍然出现(我再次清除了符号缓存)。结果是发布版本的默认值也是无校验和的,我必须自己在linker>advanced properties中设置它,然后C消失了。在中,还可以设置为调试构建。