【问题标题】:Access Violation In C applicationC 应用程序中的访问冲突
【发布时间】:2013-10-24 12:03:18
【问题描述】:

乡亲

我的 C / C++ 应用程序 (VC 6.0) 出现崩溃 它看起来是随机的,但所有实例都与 new / malloc 相关。我的代码中有一个小型转储处理程序,该处理程序在 __except 块中输出,它围绕对 OLDMain 的调用。

当我在 WinDbg 中查看这个转储时,我得到以下输出:(已修改以保护代码库)

STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
001273f0 01730000 0000042b 060a8ea8 00127424 ntdll+0x122ba
00127400 7c911bdc 01730178 0000042b 01730000 0x1730000
00127424 7c91825d 0000042b 100a8ea8 0000042b ntdll+0x11bdc
00127458 7c911c76 02730000 00001038 00127c07 ntdll+0x1825d
00127688 0081bffc 01730000 00000000 00001030 ntdll+0x11c76
001276c4 0080cf52 00001030 00127c07 00b99f11 MyProgram!_heap_alloc_base+0x13c [malloc.c @ 200]
001276ec 0080cd39 00001000 00000002 00ac1fa8 MyProgram!_heap_alloc_dbg+0x1a2 [dbgheap.c @ 378]
0012772c 0080ccbf 00001000 00000000 00000002 MyProgram!_nh_malloc_dbg+0x49 [dbgheap.c @ 248]
0012774c 008202f9 00001000 00000002 00ac1fa8 MyProgram!_malloc_dbg+0x1f [dbgheap.c @ 165]
00127774 00817dfc 00b67668 00127c07 00b99f11 MyProgram!_getbuf+0x59 [_getbuf.c @ 59]
001277a0 00818d4f 00000032 00b67668 00127af1 MyProgram!_flsbuf+0x13c [_flsbuf.c @ 153]
001277b4 00818df7 00000032 00b67668 0012786c MyProgram!write_char+0x4f [output.c @ 1113]
001277cc 00818ba5 00127af1 00000009 00b67668 MyProgram!write_string+0x37 [output.c @ 1251]
00127a9c 00809785 00b67668 00b1653a 00127ae0 MyProgram!_output+0xc65 [output.c @ 1007]
00127acc 005ad453 00b67668 00b16538 00127af0 MyProgram!fprintf+0x95 [fprintf.c @ 64]
00127c08 005acfd9 00127c30 00b16398 00127d4c MyProgram!WriteStringToFile+0x150 [C:\PATH_TO_SOURCE\LIB_Methods.cpp @ 11562]
00127d2c 004c0507 00af445c 00127d4c 0012e3bc MyProgram!WriteLog+0x594 [C:\PATH_TO_SOURCE\LIB_Methods.cpp @ 11468]
00127e84 005fd45c 00b25a78 00b258f9 00b99f11 MyProgram!WriteTimingsText+0x7c [C:\PATH_TO_SOURCE\PROM_Methods.cpp @ 2711]
0012e55c 005fd210 0000008a fffff2de 0012e6c4 MyProgram!_C_S_Method+0x113 [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 8681]
0012e940 0045dd6c 0012e810 00b24d16 00000000 MyProgram!_ST_Method+0x407e [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 8581]
0012eaf4 005f7827 0012eccc 00b9b038 0012ed64 MyProgram!_K_ST_Method+0x246 [C:\PATH_TO_SOURCE\FX_Methods.cpp @ 3306]
0012edc4 005f18b1 0012f41c 0012f424 cccccccc MyProgram!_N_I_Method+0x3b6a [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 5946]
0012f418 007ba243 00b5b950 00320030 00300034 MyProgram!OLDMain+0x1dd6 [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 2489]
0012ff30 00815546 00400000 00000000 00142368 MyProgram!WinMain+0x70f [C:\PATH_TO_SOURCE\MyProgram.cpp @ 866]
0012ffc0 7c816d4f 00320030 00300034 7ffd5000 MyProgram!WinMainCRTStartup+0x126 [crt0.c @ 198]
0012fff0 00000000 00815420 00000000 00000000 kernel32+0x16d4f

我已经查看了与 new 相关的崩溃中的其他堆栈,在这种情况下,正在创建的 clss 不需要,因为它没有配置为这样做,我添加了对配置的检查并重新运行。

这个问题似乎被推得更远了。

此时我不确定如何弄清楚为什么 Malloc / new 失败了?对我接下来可以做什么有什么建议吗?


完整的 Windbg 输出


*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

*** WARNING: Unable to verify checksum for MyProgram.exe
*** WARNING: Unable to verify timestamp for kernel32.dll
*** ERROR: Module load completed but symbols could not be loaded for kernel32.dll
***** OS symbols are WRONG. Please fix symbols to do analysis.

Unable to load image C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll, Win32 error 0n2
*** WARNING: Unable to verify timestamp for mscorwks.dll
*** ERROR: Module load completed but symbols could not be loaded for mscorwks.dll
Unable to load image C:\WINDOWS\system32\ole32.dll, Win32 error 0n2
*** WARNING: Unable to verify timestamp for ole32.dll
*** ERROR: Module load completed but symbols could not be loaded for ole32.dll
Unable to load image C:\WINDOWS\system32\user32.dll, Win32 error 0n2
*** WARNING: Unable to verify timestamp for user32.dll
*** ERROR: Module load completed but symbols could not be loaded for user32.dll
*** WARNING: Unable to verify timestamp for wdmaud.drv
*** ERROR: Module load completed but symbols could not be loaded for wdmaud.drv
*** WARNING: Unable to verify timestamp for dsound.dll
*** ERROR: Module load completed but symbols could not be loaded for dsound.dll
*** WARNING: Unable to verify timestamp for dmime.dll
*** ERROR: Module load completed but symbols could not be loaded for dmime.dll
*** WARNING: Unable to verify timestamp for dmsynth.dll
*** ERROR: Module load completed but symbols could not be loaded for dmsynth.dll
*** WARNING: Unable to verify checksum for SOBase11.dll
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for SOBase11.dll - 
*** WARNING: Unable to verify checksum for PortMg10.dll
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for PortMg10.dll - 
*** WARNING: Unable to verify checksum for Porthcom.dll
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for Porthcom.dll - 
*** WARNING: Unable to verify timestamp for mfc42.dll
*** ERROR: Module load completed but symbols could not be loaded for mfc42.dll
*** WARNING: Unable to verify checksum for PtrIO15.dll
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for PtrIO15.dll - 
*** WARNING: Unable to verify timestamp for SoDspL13.dll
*** ERROR: Module load completed but symbols could not be loaded for SoDspL13.dll
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for GdiPlus.dll - 
Unable to load image C:\WINDOWS\system32\rpcrt4.dll, Win32 error 0n2
*** WARNING: Unable to verify timestamp for rpcrt4.dll
*** ERROR: Module load completed but symbols could not be loaded for rpcrt4.dll
*** WARNING: Unable to verify timestamp for KbwMSRDrv.dll
*** ERROR: Module load completed but symbols could not be loaded for KbwMSRDrv.dll
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
            2) the file mscordacwks.dll that matches your version of mscorwks.dll is 
                in the version directory
            3) or, if you are debugging a dump file, verify that the file 
                mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
            4) you are debugging on the same architecture as the dump file.
                For example, an IA64 dump file must be debugged on an IA64
                machine.

You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.

If you are debugging a minidump, you need to make sure that your executable
path is pointing to mscorwks.dll as well.
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
            2) the file mscordacwks.dll that matches your version of mscorwks.dll is 
                in the version directory
            3) or, if you are debugging a dump file, verify that the file 
                mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
            4) you are debugging on the same architecture as the dump file.
                For example, an IA64 dump file must be debugged on an IA64
                machine.

You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.

If you are debugging a minidump, you need to make sure that your executable
path is pointing to mscorwks.dll as well.
GetPageUrlData failed, server returned HTTP status 404
URL requested: http://watson.microsoft.com/StageOne/MyProgram_exe/0_0_0_0/ntdll_dll/5_1_2600_2180/000122ba.htm?Retriage=1

FAULTING_IP: 
ntdll+122ba
7c9122ba ??              ???

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 7c9122ba (ntdll+0x000122ba)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 00000000
Attempt to read from address 00000000

PROCESS_NAME:  MyProgram.exe

ADDITIONAL_DEBUG_TEXT:  
Use '!findthebuild' command to search for the target build information.
If the build information is available, run '!findthebuild -s ; .reload' to set symbol path and load symbols.

FAULTING_MODULE: 7c900000 ntdll

DEBUG_FLR_IMAGE_TIMESTAMP:  5268f887

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

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

EXCEPTION_PARAMETER1:  00000000

EXCEPTION_PARAMETER2:  00000000

READ_ADDRESS:  00000000 

FOLLOWUP_IP: 
MyProgram!_heap_alloc_base+13c [malloc.c @ 200]
0081bffc 8b4df0          mov     ecx,dword ptr [ebp-10h]

MOD_LIST: <ANALYSIS/>

MANAGED_STACK: !dumpstack -EE
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
            2) the file mscordacwks.dll that matches your version of mscorwks.dll is 
                in the version directory
            3) or, if you are debugging a dump file, verify that the file 
                mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
            4) you are debugging on the same architecture as the dump file.
                For example, an IA64 dump file must be debugged on an IA64
                machine.

You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.

If you are debugging a minidump, you need to make sure that your executable
path is pointing to mscorwks.dll as well.

FAULTING_THREAD:  000007fc

BUGCHECK_STR:  APPLICATION_FAULT_NULL_POINTER_READ_WRONG_SYMBOLS

PRIMARY_PROBLEM_CLASS:  NULL_POINTER_READ

DEFAULT_BUCKET_ID:  NULL_POINTER_READ

IP_ON_HEAP:  01730000

FRAME_ONE_INVALID: 1

LAST_CONTROL_TRANSFER:  from 01730000 to 7c9122ba

STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
001273f0 01730000 0000042b 060a8ea8 00127424 ntdll+0x122ba
00127400 7c911bdc 01730178 0000042b 01730000 0x1730000
00127424 7c91825d 0000042b 100a8ea8 0000042b ntdll+0x11bdc
00127458 7c911c76 02730000 00001038 00127c07 ntdll+0x1825d
00127688 0081bffc 01730000 00000000 00001030 ntdll+0x11c76
001276c4 0080cf52 00001030 00127c07 00b99f11 MyProgram!_heap_alloc_base+0x13c [malloc.c @ 200]
001276ec 0080cd39 00001000 00000002 00ac1fa8 MyProgram!_heap_alloc_dbg+0x1a2 [dbgheap.c @ 378]
0012772c 0080ccbf 00001000 00000000 00000002 MyProgram!_nh_malloc_dbg+0x49 [dbgheap.c @ 248]
0012774c 008202f9 00001000 00000002 00ac1fa8 MyProgram!_malloc_dbg+0x1f [dbgheap.c @ 165]
00127774 00817dfc 00b67668 00127c07 00b99f11 MyProgram!_getbuf+0x59 [_getbuf.c @ 59]
001277a0 00818d4f 00000032 00b67668 00127af1 MyProgram!_flsbuf+0x13c [_flsbuf.c @ 153]
001277b4 00818df7 00000032 00b67668 0012786c MyProgram!write_char+0x4f [output.c @ 1113]
001277cc 00818ba5 00127af1 00000009 00b67668 MyProgram!write_string+0x37 [output.c @ 1251]
00127a9c 00809785 00b67668 00b1653a 00127ae0 MyProgram!_output+0xc65 [output.c @ 1007]
00127acc 005ad453 00b67668 00b16538 00127af0 MyProgram!fprintf+0x95 [fprintf.c @ 64]
00127c08 005acfd9 00127c30 00b16398 00127d4c MyProgram!WriteStringToFile+0x150 [C:\PATH_TO_SOURCE\LIB_Methods.cpp @ 11562]
00127d2c 004c0507 00af445c 00127d4c 0012e3bc MyProgram!WriteLog+0x594 [C:\PATH_TO_SOURCE\LIB_Methods.cpp @ 11468]
00127e84 005fd45c 00b25a78 00b258f9 00b99f11 MyProgram!WriteTimingsText+0x7c [C:\PATH_TO_SOURCE\PROM_Methods.cpp @ 2711]
0012e55c 005fd210 0000008a fffff2de 0012e6c4 MyProgram!_C_S_Method+0x113 [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 8681]
0012e940 0045dd6c 0012e810 00b24d16 00000000 MyProgram!_ST_Method+0x407e [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 8581]
0012eaf4 005f7827 0012eccc 00b9b038 0012ed64 MyProgram!_K_ST_Method+0x246 [C:\PATH_TO_SOURCE\FX_Methods.cpp @ 3306]
0012edc4 005f18b1 0012f41c 0012f424 cccccccc MyProgram!_N_I_Method+0x3b6a [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 5946]
0012f418 007ba243 00b5b950 00320030 00300034 MyProgram!OLDMain+0x1dd6 [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 2489]
0012ff30 00815546 00400000 00000000 00142368 MyProgram!WinMain+0x70f [C:\PATH_TO_SOURCE\MyProgram.cpp @ 866]
0012ffc0 7c816d4f 00320030 00300034 7ffd5000 MyProgram!WinMainCRTStartup+0x126 [crt0.c @ 198]
0012fff0 00000000 00815420 00000000 00000000 kernel32+0x16d4f


STACK_COMMAND:  ~0s; .ecxr ; kb

FAULTING_SOURCE_CODE:  
No source found for 'malloc.c'


SYMBOL_STACK_INDEX:  5

SYMBOL_NAME:  MyProgram!_heap_alloc_base+13c

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: MyProgram

IMAGE_NAME:  MyProgram.exe

BUCKET_ID:  WRONG_SYMBOLS

FAILURE_BUCKET_ID:  NULL_POINTER_READ_c0000005_MyProgram.exe!_heap_alloc_base

WATSON_STAGEONE_URL:  http://watson.microsoft.com/StageOne/MyProgram_exe/0_0_0_0/5268f887/ntdll_dll/5_1_2600_2180/411096b4/c0000005/000122ba.htm?Retriage=1

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

编辑:

我已经注释掉了WriteStringToFile,只是为了表明它会再次崩溃,这里是另一个调用堆栈:heap_alloc 中唯一的共同点,现在我可以看到两个调用堆栈之间的一件事是相同的 NULL指针在下面一行:是在 _N_I_Method 中 Null 指针开始的地方还是这里有效?

0012edc4 005f18b1 0012f41c 0012f424 **cccccccc** MyProgram!_N_I_Method+0x3b6a [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 5946]

新堆栈


STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
00127b54 0012e3bc 00b99f11 00000000 00000000 ntdll+0x3426d
00127d78 0081bffc 01730000 00000000 00000040 0x12e3bc
00127db4 0080cf52 00000040 0012e3bc 00b99f11 MyProgram!_heap_alloc_base+0x13c [malloc.c @ 200]
00127ddc 0080cd39 00000014 00000001 00000000 MyProgram!_heap_alloc_dbg+0x1a2 [dbgheap.c @ 378]
00127e1c 0080cce6 00000014 00000001 00000001 MyProgram!_nh_malloc_dbg+0x49 [dbgheap.c @ 248]
00127e38 008089bf 00000014 00000001 00b86f20 MyProgram!_nh_malloc+0x16 [dbgheap.c @ 197]
00127e4c 0052966a 00000014 00b99f11 cccccccc MyProgram!operator new+0xf [new.cpp @ 24]
00127e88 005ff32c 00b258f9 00b99f11 00000000 MyProgram!CMessaging::SendMsg_Finished+0x43 [C:\PATH_TO_SOURCE\CMessaging.cpp @ 1703]
0012e55c 005fd210 0000008a fffff2de 0012e6c4 MyProgram!_C_S_Method+0x1fe3 [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 9824]
0012e940 0045dd6c 0012e810 00b24d16 00000000 MyProgram!_ST_Method+0x407e [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 8581]
0012eaf4 005f7827 0012eccc 00b9b038 0012ed64 MyProgram!_K_ST_Method+0x246 [C:\PATH_TO_SOURCE\FX_Methods.cpp @ 3306]
0012edc4 005f18b1 0012f41c 0012f424 cccccccc MyProgram!_N_I_Method+0x3b6a [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 5946]
0012f418 007ba243 00b5b950 80000001 01b5d678 MyProgram!Oldmain+0x1dd6 [C:\PATH_TO_SOURCE\SAL_Methods.cpp @ 2489]
0012ff30 00815546 00400000 00000000 00142368 MyProgram!WinMain+0x70f [C:\PATH_TO_SOURCE\MyProgram.cpp @ 866]
0012ffc0 7c816d4f 80000001 01b5d678 7ffdf000 MyProgram!WinMainCRTStartup+0x126 [crt0.c @ 198]
0012fff0 00000000 00815420 00000000 00000000 kernel32+0x16d4f

【问题讨论】:

  • 尝试使用一些内存泄漏检测器。在 Linux 上我推荐valgrind ....
  • @BasileStarynkevitch 这个问题上面写满了 Microsoft Windows...
  • 我知道这个问题提到了 Windows(但我不知道 Windows 并且不使用它),但我不知道 Windows 上的 valgrind 等价物是什么。许多年前,您或许可以购买Purify。不知道有没有这个产品。尽管如此,OP 必须找到等效的内存泄漏检测器。
  • 代码在您的函数 WriteStringToFile 中看起来如何?似乎你在那里调用 fprintf 时出错
  • 老实说,该方法无关紧要,我可以像在其他情况下所做的那样将其注释掉,并且错误只会发生在代码中的其他地方。这不会在您第一次运行应用程序时发生,其随机相同的代码路径可以使用相同的测试脚本执行数千次并且没有问题,或者在其他情况下它可能只执行一个测试

标签: c++ c memory memory-management out-of-memory


【解决方案1】:

Malloc/new 失败,通常是因为堆已经损坏。对于您的情况,可能有两个原因:

  1. 堆被你自己的代码搞砸了。
  2. 不匹配的运行时库。您仍在使用 VC 6++ 进行编码,但其他 DLL,我认为它们中的大多数是用更高版本编译的 VC的版本,所以应该有多个windows运行时 进程中的库(msvcrt.dll)。如果一个内存被分配 一个运行时库,并由另一个运行时库释放 可能会导致堆损坏,因为不同的运行时库可能 有不同的 malloc 和 free 实现。

【讨论】:

  • 谢谢马特,是的,我认为堆损坏是问题所在,看看我的编辑是否有可能是 _N_I_Method 堆栈中的 cccccccc 是问题的根源,这在两次崩溃中都很常见?
  • 这只是意味着堆在该行代码之前已损坏。当堆损坏时,通常会在下一次 malloc 时崩溃,因为运行时库通常会在分配新内存之前验证堆。一个工具是DebugDiag,它是免费的,它可以帮助你调试内存问题,你可以试试。另一个工具是应用程序验证器
  • 谢谢马特,我有这个权利,在我调用 _N_I_Method 之前堆已损坏,从 MiniDump 中我可以看到堆损坏的原因还是我需要使用 DebugDiag 或 AppVerify 再次运行?
  • 是的,它已经损坏了。您需要再次运行该程序。
【解决方案2】:
At this point i am unsure how to figure out why Malloc / new are failing? Any suggestions for what i can do next?

如果您遇到堆栈帧异常,那么您的代码中很可能存在缓冲区溢出。

如果您没有合适的工具来帮助您,我建议您结合使用代码审查(重点关注指针和缓冲区溢出)和经典调试。

对于经典调试,我的意思是通过首先一次运行一段代码来查明问题,直到您遇到崩溃或看到一个被覆盖的变量。然后逐行重新运行最后一个部分,直到找到它失败的地方。修复错误。 重复直到所有的测试用例都工作。

【讨论】:

  • 感谢 Klas,我已经通过测试伙伴运行了这个,它在调试下没有失败,这可能是由于调试器填充了缓冲区。 Devpartner 除了一些悬空指针之外没有显示任何问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-04
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多