从不同操作系统检索到的故障转储指向消息循环。如何从那里到达故障位置? (TeamViewer 使我的进程崩溃。)

Posted

技术标签:

【中文标题】从不同操作系统检索到的故障转储指向消息循环。如何从那里到达故障位置? (TeamViewer 使我的进程崩溃。)【英文标题】:Crash dump retrieved from a different OS points to message loop. How to get to the fault location from there? (TeamViewer crashes my process.) 【发布时间】:2016-07-09 02:55:26 【问题描述】:

我们软件的一位客户抱怨说它在他的 Windows XP 机器上崩溃了。我让他下载ProcDump 并通过它运行我们的流程:

procdump -e -ma -w myproc.exe

为此用户通过电子邮件向我收集了崩溃转储.dmp 文件。

然后,我将.dmp 文件与进程的原始.exe 图像文件以及.pdb 文件放在同一文件夹中,并通过Visual Studio 2010 运行.dmp 文件:

然后,当我单击“仅使用本机调试”时,VS 显示了 MFC 的消息循环函数的源代码以及 DispatchMessage 调用后的指针位置(见绿色箭头):

调用堆栈也没有多大帮助:

当我跳转到报告的故障地址时,我什么也没得到:

该应用程序在VS 2008 中编译为基于对话框的 C++/MFC 应用程序。

所以我正在检查 .dmp 文件的大小,它是 26.6 MB。里面有数据。我的问题是如何从中获得更多有用的信息来帮助查明源代码中的故障位置?

PS。作为事后的想法,当我在 Windows 8.1 上运行此故障转储.dmp 文件时,我发现在 Windows XP 上发生了崩溃。这就是我在堆栈跟踪中得到垃圾的原因吗?

编辑:如果我尝试查看 MSG 结构中的参数,DispatchMessage 被调用时,这就是我在反汇编程序中得到的结果:

当我尝试查看pState 中的值时,我得到symbol not found

编辑2:关于模块和加载到故障EIP 地址的模块。 0x1963AB50 的内存插槽似乎没有被任何模块占用:

编辑 3: 抱歉,时间太长了。我最终在WinDbg 中打开了故障转储并对其执行了!analyze -v 命令。这是输出。似乎丢失/卸载的 DLL 是 tv_w32.dll:

Microsoft (R) Windows Debugger Version 10.0.10586.567 X86
Copyright (c) Microsoft Corporation. All rights reserved.


Loading Dump File [C:\Users\User\Desktop\Myproc\Release\Myproc.exe_160708_141237.dmp]
User Mini Dump File with Full Memory: Only application data is available

Comment: '
*** procdump -e -ma -w Myproc.exe
*** Unhandled exception: C0000005.ACCESS_VIOLATION'

************* Symbol Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*c:\MyServerSymbols*https://msdl.microsoft.com/download/symbols
Symbol search path is: srv*c:\MyServerSymbols*https://msdl.microsoft.com/download/symbols
Executable search path is: 
Windows XP Version 2600 (Service Pack 3) MP (2 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Fri Jul  8 05:12:39.000 2016 (UTC - 7:00)
System Uptime: 9 days 6:05:50.960
Process Uptime: 3 days 5:08:52.000
.....................................
Loading unloaded module list
..
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(ba4.4a4): Access violation - code c0000005 (first/second chance not available)
eax=00000001 ebx=00000002 ecx=7c92741c edx=7c98e174 esi=1963ab50 edi=1963ab50
eip=19608536 esp=0012ee3c ebp=0012ee5c iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
<Unloaded_tv_w32.dll>+0x8536:
19608536 ??              ???
0:000> .bugcheck
               ^ Syntax error in '.bugcheck'
0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************


DUMP_CLASS: 2

DUMP_QUALIFIER: 400

CONTEXT:  (.ecxr)
eax=00000001 ebx=00000002 ecx=7c92741c edx=7c98e174 esi=1963ab50 edi=1963ab50
eip=19608536 esp=0012ee3c ebp=0012ee5c iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
<Unloaded_tv_w32.dll>+0x8536:
19608536 ??              ???
Resetting default scope

FAULTING_IP: 
tv_w32!unloaded+8536
19608536 ??              ???

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 19608536 (<Unloaded_tv_w32.dll>+0x00008536)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 19608536
Attempt to read from address 19608536

DEFAULT_BUCKET_ID:  BAD_INSTRUCTION_PTR

PROCESS_NAME:  Myproc.exe

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

EXCEPTION_CODE_STR:  c0000005

EXCEPTION_PARAMETER1:  00000000

EXCEPTION_PARAMETER2:  19608536

READ_ADDRESS:  19608536 

FOLLOWUP_IP: 
tv_w32!unloaded+8536
19608536 ??              ???

FAILED_INSTRUCTION_ADDRESS: 
tv_w32!unloaded+8536
19608536 ??              ???

WATSON_BKT_PROCSTAMP:  576c0d97

WATSON_BKT_PROCVER:  1.5.16.0

PROCESS_VER_PRODUCT:  Myproc Name

WATSON_BKT_MODULE:  unknown

WATSON_BKT_MODVER:  0.0.0.0

WATSON_BKT_MODOFFSET:  19608536

MODLIST_WITH_TSCHKSUM_HASH:  8b7920bcb3af2eb1b97366fd0663a3798ab285ea

MODLIST_SHA1_HASH:  b5acbaed45de37ad3c73ee4478c8f6678e94eaa6

NTGLOBALFLAG:  0

APPLICATION_VERIFIER_FLAGS:  0

PRODUCT_TYPE:  1

SUITE_MASK:  272

DUMP_FLAGS:  3

DUMP_TYPE:  0

APP:  Myproc.exe

ANALYSIS_SESSION_HOST:  DESKTOP-ABC

ANALYSIS_SESSION_TIME:  07-08-2016 22:18:58.0444

ANALYSIS_VERSION: 10.0.10586.567 x86fre

IP_MODULE_UNLOADED: 
tv_w32!unloaded+8536
19608536 ??              ???

THREAD_ATTRIBUTES: 
OS_LOCALE:  DEU

PROBLEM_CLASSES: 



BAD_INSTRUCTION_PTR
    Tid    [0x4a4]
    Frame  [0x00]: tv_w32!unloaded



INVALID_POINTER_READ
    Tid    [0x4a4]
    Frame  [0x00]: tv_w32!unloaded


BUGCHECK_STR:  BAD_INSTRUCTION_PTR_INVALID_POINTER_READ

LAST_CONTROL_TRANSFER:  from 00000000 to 19608536

STACK_TEXT:  
0012ee38 00000000 19608648 ffff071b 00000000 <Unloaded_tv_w32.dll>+0x8536


THREAD_SHA1_HASH_MOD_FUNC:  0959aaead905d5402017a9de12facac3929f71c3

THREAD_SHA1_HASH_MOD_FUNC_OFFSET:  52f8c4ddebdd2e855f90e79f96f6fc29a470ad1d

THREAD_SHA1_HASH_MOD:  2e69fc2d39893b6d7d9991dcc4967479dbafb5c5

SYMBOL_STACK_INDEX:  0

SYMBOL_NAME:  tv_w32!unloaded+8536

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: tv_w32

IMAGE_NAME:  tv_w32.dll

DEBUG_FLR_IMAGE_TIMESTAMP:  573435d6

STACK_COMMAND:  .ecxr ; kb

FAILURE_BUCKET_ID:  BAD_INSTRUCTION_PTR_c0000005_tv_w32.dll!unloaded

BUCKET_ID:  BAD_INSTRUCTION_PTR_INVALID_POINTER_READ_UNLOADED_IP_tv_w32!unloaded+8536

PRIMARY_PROBLEM_CLASS:  BAD_INSTRUCTION_PTR_INVALID_POINTER_READ_UNLOADED_IP_tv_w32!unloaded+8536

BUCKET_ID_OFFSET:  8536

BUCKET_ID_MODULE_STR:  tv_w32

BUCKET_ID_MODTIMEDATESTAMP:  573435d6

BUCKET_ID_MODCHECKSUM:  45ff9

BUCKET_ID_MODVER_STR:  0.0.0.0

BUCKET_ID_PREFIX_STR:  BAD_INSTRUCTION_PTR_INVALID_POINTER_READ_UNLOADED_IP_

FAILURE_PROBLEM_CLASS:  BAD_INSTRUCTION_PTR

FAILURE_EXCEPTION_CODE:  c0000005

FAILURE_IMAGE_NAME:  tv_w32.dll

FAILURE_FUNCTION_NAME:  unloaded

BUCKET_ID_FUNCTION_STR:  unloaded

FAILURE_SYMBOL_NAME:  tv_w32.dll!unloaded

TARGET_TIME:  2016-07-08T12:12:39.000Z

OSBUILD:  2600

OSSERVICEPACK:  6532

SERVICEPACK_NUMBER: 6

OS_REVISION: 0

OSPLATFORM_TYPE:  x86

OSNAME:  Windows XP

OSEDITION:  Windows XP WinNt (Service Pack 3) SingleUserTS

USER_LCID:  0

OSBUILD_TIMESTAMP:  2014-03-12 03:48:40

ANALYSIS_SESSION_ELAPSED_TIME: e0a

ANALYSIS_SOURCE:  UM

FAILURE_ID_HASH_STRING:  um:bad_instruction_ptr_c0000005_tv_w32.dll!unloaded

FAILURE_ID_HASH:  7c7c5a5b-462a-0301-1674-660f1336c576

Followup:     MachineOwner
---------

【问题讨论】:

AfxInternalPumpMessage 函数中,你能看到最后处理的消息是什么吗?你有那个消息的处理程序吗?那个处理程序是做什么的?处理程序函数是否包含任何本地数组,并且您超出了它的范围?因为这类错误,以及损坏的堆栈,主要是因为在您自己的一个或多个函数中越界写入局部变量。如果代码不是很大,那么请人审查它可能是个好主意。或者至少尝试添加一些调试日志记录和跟踪。 @JoachimPileborg:谢谢。我更新了我原来的问题。 (见编辑。) 您正在获取消息处理程序的源代码,因为这是调试器在堆栈上发现的具有源代码的第一帧。 EDI 寄存器的内容是崩溃现场的任何内容,即 0x1963AB50。查看Modules 选项卡以查看在该地址加载了什么DLL。您的发布版本是否包含调试符号? @1201ProgramAlarm:我更新了我的帖子。 (请参阅编辑 2。)回答您的问题:是的,正如您所见,符号已加载到我的 exe 中。至于该故障地址处的模块,则似乎没有。虽然我不确定那缺少的xpsp2res.dll 是什么?这不是我的流程所依赖的东西。 xpsp2res.dll 具有作为 XP Service Pack 2 的一部分添加到 Windows 并自动加载的资源 (?)。您的程序可能会丢失(从损坏的堆栈或损坏的函数指针)并徘徊到没有代码的地方(并且堆栈转储是垃圾),或者那里的代码已经被卸载(在异常处理期间; 或者它可能是在删除使用它的对象之前手动卸载的 DLL 中的虚拟函数;或者是托管代码或其他运行时生成的代码)。 【参考方案1】:

只是想在这里发布它以供遇到此问题的其他人使用。经过几个小时的故障转储文件挖掘,最终WinDbg 能够查明罪魁祸首(阅读我在问题本身中的帖子。)

底线是我们的客户使用 TeamViewer 和他们的 Quick Connect 选项,basically injects 第三方 UI 元素进入运行程序。这与明显的内存泄漏相结合(参见我上面的 OP 和 xpsp2res.dll 模块的 discussion of the use)导致了崩溃。

实际崩溃发生在tv_w32.dll 中,在生成转储之前已卸载。由于我没有 TeamViewer 的源文件,也没有与我们的软件有任何关系的源文件,所以目前我能做的几乎就是这些。

PS。 作为底线,在分析了转储之后,我强烈建议人们不要将 TeamViewer 用作首选远程桌面解决方案。它似乎有很多错误并导致内存泄漏。

【讨论】:

您的分析很棒。我今天也遇到了类似的崩溃(tv_x64.dll,确切版本是 12.0.83369) - 并通过关闭 Teamviewer 解决了它。所以这里 一个错误。 -- 但是,我不得不说“似乎非常有问题”和“强烈建议不要这样做”是so。我们多年来一直在使用电视,这是我遇到的第一个确认问题。这是一个出色的工具,为我们节省了大量时间。所以错误:是的。但仍然是一个很好的工具。 @MartinBa:Ref1,Ref2,Ref3,ref4。在深入研究了带有调试器的 TeamViewer 代码后,我完全支持我的“buggy”和insecure 声明。 #SloppyCode 天哪。软件有漏洞。令人震惊。 (或者可能不是。1 岁的大众媒体对所有同一事件的报道试图证明什么?)

以上是关于从不同操作系统检索到的故障转储指向消息循环。如何从那里到达故障位置? (TeamViewer 使我的进程崩溃。)的主要内容,如果未能解决你的问题,请参考以下文章

如何增加在 Discord 频道上检索到的消息数量(python)

将自定义数据包含到 iOS 故障转储中

从故障转储中查找 GDI/用户资源使用情况

是否可以在本机 C 中读取 logcat?

Windows消息机制

从核心转储中检索可执行文件