为什么使用Windbg的pdb文件的校验和失败?

时间:2017-03-22 18:23:35

标签: c++ visual-studio-2015 windbg

我在VS2015中创建了一个简单的控制台演示应用程序来模拟崩溃。我用windbg运行可执行文件来调试它以用于演示目的。应用程序按预期运行并崩溃。

但是这时候windbg很奇怪。

当我在同一台机器上构建它时,我看不到与调用堆栈函数相对应的代码。调用堆栈旁边的源代码行不是源代码所在的位置,它几乎没有引用我的示例代码(单个main.cpp文件)。

0:000> kb
 # ChildEBP RetAddr  Args to Child              
00 0036f7e8 77a18e12 ffffffff 00000000 00000000 ntdll!NtTerminateProcess+0x12
01 0036f804 756c79c4 00000000 77e8f3b0 ffffffff ntdll!RtlExitUserProcess+0x85
02 0036f818 0f4891b8 00000000 0036f840 0f48916c kernel32!ExitProcessStub+0x12
03 0036f824 0f48916c 00000000 0036f84c 0036f850 ucrtbased!exit_or_terminate_process+0x38 [d:\rs1\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp @ 130]
04 0036f840 0f489452 00000000 00000000 00000000 ucrtbased!common_exit+0x5c [d:\rs1\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp @ 265]
05 0036f854 00e42348 00000000 c0bb032f 00000000 ucrtbased!exit+0x12 [d:\rs1\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp @ 278]
06 0036f8b0 00e421cd 0036f8c0 00e424e8 0036f8cc Project1!__scrt_common_main_seh+0x168 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 262]
07 0036f8b8 00e424e8 0036f8cc 756c336a 7efde000 Project1!__scrt_common_main+0xd [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 296]
08 0036f8c0 756c336a 7efde000 0036f90c 779f9902 Project1!wmainCRTStartup+0x8 [f:\dd\vctools\crt\vcstartup\src\startup\exe_wmain.cpp @ 17]
09 0036f8cc 779f9902 7efde000 7dbc800d 00000000 kernel32!BaseThreadInitThunk+0xe
0a 0036f90c 779f98d5 00e4134d 7efde000 00000000 ntdll!__RtlUserThreadStart+0x70
0b 0036f924 00000000 00e4134d 7efde000 00000000 ntdll!_RtlUserThreadStart+0x1b

当我运行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命令时,它会在C模块旁边显示Project1,这意味着校验和不匹配,但为什么呢?它建立在同一台机器上,符号文件应该匹配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

对于主private pdb symbols模块,它实际上甚至没有说Project1.exe,几乎就像找不到符号一样!?

校验和问题也反映在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无法找到并且没有产生有意义的结果呢?

2 个答案:

答案 0 :(得分:1)

  

当我运行lm Project1.exe时,它无法理解Project1.exe

new_dct = {k:{key:val for key,val in v.items()} for k,v in dct.items()} print(new_dct) >>> {'A': {'food': 30, 'menu': 19, 'good': 15}, 'B': {'chicken': 10, 'one': 5}} 命令失败有两个原因:

  1. 模块名称为lm Project1.exe,而非Project1
  2. 该命令缺少另一个m:Project1.exe
  3.   

    它实际上甚至没有对主Project1.exe模块说lm m Project1几乎就像它找不到符号一样!?

    我说发布版本是正常的。私人信息被剥夺。

      

    它显示Project1模块旁边的C,这意味着校验和不匹配

    关于校验和的C,帮助说:

    private pdb symbols

    恕我直言,为了识别PDB,时间戳足够可靠,不需要校验和。您可以使用chkmatch检查您的可执行文件是否与您的符号匹配。

    我在Debug和Release版本中获得了C#程序的C警告,但我没有问题。

    在评论中你说:

      

    我的系统上甚至没有f:\ dd文件夹。

    这可能是由链接器生成的。您使用静态链接,这会在您的可执行文件中嵌入一些C ++运行时内容,其中源是由Microsoft编译的。

    其他人说:

      

    它正在从一个不寻常的目录中加载Project1符号,

    这是真的,但应用程序的符号可以存储在符号存储中,具体取决于符号路径配置。

    How to set up symbols in WinDbg。在你的情况下它应该是

    The checksum is missing, not accessible, or equal to zero.
    
      

    为什么windbg无法找到东西

    你期待找到什么?

      

    并没有产生有意义的结果?

    输出的哪一部分对你没有意义?

答案 1 :(得分:1)

你需要在你的项目中设置/ release开关为chksum设置默认的调试buulds是nochksum
发布buikds的默认值是setchksum

Unable to verify checksum for exe

https://msdn.microsoft.com/en-us/library/h8ksa72a.aspx

要将lm与modulename一起使用,您需要-m开关。

像。 Lm -m pro *
您可以将通配符用于modname。 Windbg将显示与模式匹配的所有模块

在。 F:\ dd路径来自crt源。它们在您的vs src文件夹中可用。因为它们是硬编码路径

您可能需要将src文件夹复制到本地计算机中的确切目录结构

Viz md f:\ dd ........ \和xcopy整个src文件夹到该路径。 Windbg将挑选原料

如果。您编译调试或释放您的pdb未被剥离它们保持私有pdb,除非您使用pdbcopy或binplace剥离私有符号

您的堆栈显示terminateprocess。它的意思是。您可能需要手动打开源文件,这超过了您的用户代码。使用。 Lsa ls命令

从手机键入,以便我可以进一步编辑以添加信息