【问题标题】:Can't symbolicate using WinDBG, the exe and its associated pdb无法使用 WinDBG、exe 及其关联的 pdb 进行符号化
【发布时间】:2021-01-20 16:51:16
【问题描述】:

我一直在尝试在一个项目中使用以前的同事的崩溃记者。 它在发生崩溃时输出堆栈跟踪,其中包含例如这样的内容(仅显示堆栈跟踪中最重要的行):

Event: APPLICATION_CRASH
SE EXCEPTION_ACCESS_VIOLATION at address 0x00007FF773D681E6 inside MyApp.exe loaded at base address 0x00007FF773950000 Invalid operation: read at address

作为我们构建过程的一部分,我们将导出调试信息(即使在“发布”模式下构建)并将它们保存在我们的文件服务器上,以便我们为我们交付的每个版本的软件应用程序提供匹配的调试信息.

现在,我正在尝试使用内存地址、exe、pdb 文件和 WinDBG(版本 1.0.2007.06001)查找崩溃发生的位置。 我已将所有 pdb 文件复制到我的 exe 所在的应用程序文件夹的根目录中 我正在通过开始调试-> 启动可执行文件来加载 exe。 然后我尝试在 WinDBG 中使用以下命令获取符号: u 0x00007FF773D681E6 不幸的是,无论我尝试什么,我都会得到:

0:000> u 0x00007FF773D681E6
00007ff7`73d681e6 ??              ???
                          ^ Memory access error in 'u 0x00007FF773D681E6'

我试图通过这样做来添加这个标志SYMOPT_LOAD_ANYTHING

0:000> .symopt+ 0x40
Symbol options are 0x30377:
  0x00000001 - SYMOPT_CASE_INSENSITIVE
  0x00000002 - SYMOPT_UNDNAME
  0x00000004 - SYMOPT_DEFERRED_LOADS
  0x00000010 - SYMOPT_LOAD_LINES
  0x00000020 - SYMOPT_OMAP_FIND_NEAREST
  0x00000040 - SYMOPT_LOAD_ANYTHING
  0x00000100 - SYMOPT_NO_UNQUALIFIED_LOADS
  0x00000200 - SYMOPT_FAIL_CRITICAL_ERRORS
  0x00010000 - SYMOPT_AUTO_PUBLICS
  0x00020000 - SYMOPT_NO_IMAGE_SEARCH

然后完全重新加载,使用此命令:.reload /f /i(我尝试过不使用 /i 但仍然是相同的输出)但我总是遇到相同的内存访问错误。

我做错了什么,我有什么遗漏吗?

【问题讨论】:

  • 看看!sym noisy 有没有给你带来有趣的东西 (docs.microsoft.com/en-us/windows-hardware/drivers/debugger/-sym)
  • 如果可能的话,也设置一个符号服务器意味着你可以避免几乎所有这些问题。
  • 我如何定期执行此操作,尤其是对于转储中的实际崩溃:1. 打开转储时立即使用 .symfix 2. 使用 .sympath+ full-path-to-your-pdbs 。对需要修改的所有 pdb 路径重复 (2)。 3.运行!analyze -v,然后坐等;这可能需要一段时间,具体取决于图像大小和符号。这应该让你非常接近罪魁祸首。机器架构在分析步骤之前设置很重要。如果它是 32 位 x86 转储并且您正在运行 WinDbg x64,则在步骤 (2) 和 (3) 之间需要 .effmach x86,但看起来这不是您的情况。
  • @MikeVine 我以前用过那个详细的模式,但它并没有告诉我太多,你要我在这里发布吗?什么是符号服务器?我已将所有符号放在一个地方,并将该路径添加到 WinDBG sympath,但没有成功编辑:似乎主 pdb 已正确加载
  • @WhozCraig 不幸的是,该应用程序没有生成 dmp 文件...一直是 x64 :) 我以前没有听说过分析,我会尝试你的命令并回复你 - 谢谢!

标签: c++ windows debugging windbg


【解决方案1】:

您不能在新启动的可执行文件中使用某些工具提供的任意地址 了解 ASLR(地址空间布局随机化)

您的工具还为您提供加载的基地址 使用该基地址并查看新启动的应用程序是否已加载到相同的地址

如果不同,那么您可能需要计算工具崩溃地址和基地址之间的差异,并将差异应用到新启动的应用中

类似的东西

>>> print(hex(0x00007FF773D681E6-0x00007FF773950000))
0x4181e6
>>> print(hex(0x00007FF800000000+0x4181e6))
0x7ff8004181e6
>>>

还请注意,这可能仍然会失败,因为它是读取失败,并且地址可能在应用程序中计算错误 喜欢

mov rax , xxxxxx
add rax , Result_of_some_buggy_magic() resulting in rax ==0x00007FF773D681E6 
mov rdx, [rax] 

最后但并非最不重要的一点是不要在文件夹中转储 pdb 设置适当的缓存
并使用 symstore.exe 将它们存储在该缓存中
使用环境变量 _NT_SYMBOL_PATH 来定义缓存和符号服务器
因此,您的所有符号都位于某种层次结构中,并且可以通过 windbg 轻松定位,而无需您手动干预

演示如何使用 symstore.exe 在 _NT_SYMBOL_PATH 环境变量指向的下游存储中存储 pdb 的示例演练 滚动到最后查看路径

:\>symstore add /f printf.pdb /s f:\symbols /t somecrap
Finding ID...  0000000001

SYMSTORE: Number of files stored = 1
SYMSTORE: Number of errors = 0
SYMSTORE: Number of files ignored = 0

:\>set _NT
_NT_SYMBOL_PATH=srv*f:\symbols*https://msdl.microsoft.com/download/symbols


:\>ls -lRg f:\symbols\printf.pdb
'f:\symbols\printf.pdb':
total 0
drwxr-xr-x 1 197121 0 Jan 20 23:48 2D2A336AD93A4CB4B1E47A75C3CB78B71  << a heirarchical folder name with GUID and Age

'f:\symbols\printf.pdb/2D2A336AD93A4CB4B1E47A75C3CB78B71':
total 6421
-rw-r--r-- 1 197121 6574080 Jan 20 09:05 printf.pdb << actual pdbfile locatable with _NT_SYMBOL_PATH envvar automatically 
-rw-r--r-- 1 197121      67 Jan 20 23:48 refs.ptr

you can now copy only exe any where but your symbol will still be locatable



:\>ls -lg
total 6798
-rw-r--r-- 1 197121     667 Jan 20 09:06 compileresult.txt
-rw-r--r-- 1 197121      82 Jan 20 09:03 printf.cpp
-rwxr-xr-x 1 197121  301568 Jan 20 09:05 printf.exe
-rw-r--r-- 1 197121      59 Jan 20 09:05 printf.nativecodeanalysis.xml
-rw-r--r-- 1 197121    5283 Jan 20 09:05 printf.obj
-rw-r--r-- 1 197121 6574080 Jan 20 09:05 printf.pdb
-rw-r--r-- 1 197121   69632 Jan 20 09:05 vc140.pdb

:\>del *.pdb

:\>del *.txt

:\>del *.xml

:\>del *.obj

:\>ls -lg
total 297
-rw-r--r-- 1 197121     82 Jan 20 09:03 printf.cpp
-rwxr-xr-x 1 197121 301568 Jan 20 09:05 printf.exe


:\>cdb -c ".reload /f;lm m printf;q" printf.exe | awk "/Reading/,/quit/"
0:000> cdb: Reading initial command '.reload /f;lm m printf;q'
Reloading current modules

start             end                 module name
00000000`00b80000 00000000`00bce000   printf     (private pdb symbols)  f:\symbols\printf.pdb\2D2A336AD93A4CB4B1E47A75C3CB78B71\printf.pdb
quit: <<< windbg located the symbolfile withoutme havingto think about where i dumped it setting symbol paths and other blah blah 

【讨论】:

  • 非常感谢!会考虑尝试一下。最初的问题: - 你在哪里运行所有这些带有ls、symstore 等的命令。我应该在 PowerShell 中执行这些命令吗? - symstore add /f printf.pdb /s f:\symbols /t somecrap这里会有什么东西?
  • 我使用 cmd.exe 提升在开始菜单上固定我猜你也可以使用 power shell /t 是 symstore 的必需参数一个版本号对于这个可执行文件不存在所以使用占位符 read documentation of symstore ls iirc 在 wsl 中可用,尽管我使用 git 包中的它
  • 谢谢,将尝试让它与偏移量一起工作,因为基地址看起来已经不同了:/ 我真的想,如果我在编译我给的 exe 时创建了 PDB 文件我们的客户,我可以只加载我的 exe(这与客户在崩溃时使用的完全相同)、pdb 和瞧。我想我错了!
  • 您是否必须将C:\Program Files (x86)\Windows Kits\10\Debuggers\x64 添加到您的路径才能使用symstore、cdb 等?我已经安装了所有工具,但我必须从该文件夹启动我的 shell 才能使用它们。
  • 是的,如果不添加路径或使用 set path=%path%;c:\whatever 创建一个 bat 文件,iirc windbg 安装程序会自动执行此操作
猜你喜欢
  • 1970-01-01
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 2019-11-02
  • 2017-11-17
相关资源
最近更新 更多