why drwtson32 fails to generate the dump for 2nd C++ exception!

本文探讨了Dr.Watson在处理未捕获的C++异常时无法生成转储文件的问题,并通过深入研究发现是由于CRT的异常处理机制导致原始C++异常被覆盖。文中还提供了几种替代方案来解决此问题。

why drwtson32 fails to generate the dump for 2nd C++ exception!

原贴地址:
 http://eparg.spaces.msn.com/blog/cns!59BFC22C0E7E1A76!1213.entry
原贴时间:
2006-06-21
原贴作者:
eparg

int _tmain(int argc, _TCHAR* argv[])

{

throw 1;

return 0;

}

int _tmain(int argc, _TCHAR* argv[])

{

int *p=0;

*p=0;

return 0;

}

Use “drwtsn32.exe –i” to register Dr. Watson and execute above code. For unhandled C++ exception, Dr. Watson fails to generate the dump. For unhandled AV, the dump is created fine.

If we change the AeDebug/Debugger in registry to use windbg as the following, the dump is created fine even for unhandled C++ exception.

C:/debuggers/windbg.exe -p %ld -e %ld -c ".dump /mfh C:/myfile.dmp ;q"

Why the drwtson32 ignores the dump for unhandled C++ exception?


With almost 6 hours research, got the answer, here are the steps:

 


My 1st step is to check if drwtson32 is launched. In AeDebug, I set Debugger as drwtson32 and set Auto to 0. I also add drwtson32.exe key in Image File Execution Options, and set the debugger to windbg.exe.

 

When the C++ EH occurs, windbg gets launched and attached to drwtson32. It means the unhandled C++ EH triggers drwtson32 successfully.

 

The next step is to check why drwtson32 fails to write the dump. Since I’ve no idea about the code logic of drwtson32, I switch to AV sample as research.

 

The AV triggers drwtson32 with windbg attached. I set bp on CreateFile API and it stops on the following call stack:

 

kernel32!CreateFileW

dbgeng!WriteDumpFile+0x2c]

dbgeng!DebugClient::WriteDumpFileInternal+0x6e

dbgeng!DebugClient::WriteDumpFile2+0x34

drwtsn32!CreateDumpFile+0xda

drwtsn32!DispatchDebugEventThread+0x1c7

kernel32!BaseThreadStart+0x34

 

Now I know the dump writing logic is in DispatchDebugEventThread function. I restart with AV Sample and go through the DispatchDebugEventThread to understand the logic. The function waits for debugging event, and handles it. For DEBUG_EVENT_EXCEPTION event, it queries for the ExceptionRecord. For the AV sample, when it gets the AV ExceptionRecord, it creates the dump.

 

With above understanding, I switch back to test The C++ EH sample. The DispatchDebugEventThread function is also invoked. However, drwtson32 does not get the C++ EH ExceptionRecord so there is no dump created.

 

Ok, our next question is, why there is no C++ EH ExceptionRecord passed in.

 

Just some days ago, I posted “How to debug UnhandleExceptionHandler”. The handler should be the last chain to do with the unhandled exception. So I decide to use my own handler as a test. When my handler returns 0, no matter AV or C++ EH, drwtson32 saves the dump correctly! When my handler returns 1, the debugger in AeDebug is not triggered at all.

 

Above test shows that the problem is somehow related to the UnhandleExceptionHandler. Since CRT uses special handler to deal with C++ EH, I decide to trace the CRT handler.

 

Since windbg is convenient, I change the AeDebug to use windbg. When windbg is triggered, it shows the following two callstacks for the two samples:

 

0012f864 7c822114 ntdll!KiFastSystemCallRet

0012f868 77e99c32 ntdll!ZwWaitForMultipleObjects+0xc

0012fb30 78138c06 kernel32!UnhandledExceptionFilter+0x746

0012fb50 0040119e MSVCR80!_XcptFilter+0x6a

0012fb5c 7813dfc4 win32!__tmainCRTStartup+0x137

0012fb70 7813bc8d MSVCR80!_EH4_CallFilterFunc+0x12

0012fb98 00401644 MSVCR80!_except_handler4_common+0x8d

0012fbb4 7c82eeb2 win32!_except_handler4+0x1f

0012fbd8 7c82ee84 ntdll!ExecuteHandler2+0x26

0012fc80 7c82ecc6 ntdll!ExecuteHandler+0x24

0012fc80 00401002 ntdll!KiUserExceptionDispatcher+0xe

0012ff7c 00401176 win32!main+0x2

0012ffc0 77e523cd win32!__tmainCRTStartup+0x10f

0012fff0 00000000 kernel32!BaseProcessStart+0x23

 

 

0012f210 7c822114 ntdll!KiFastSystemCallRet

0012f214 77e99c32 ntdll!ZwWaitForMultipleObjects+0xc

0012f4dc 7813adda kernel32!UnhandledExceptionFilter+0x746

0012f814 781346b6 MSVCR80!abort+0xeb

0012f844 7815e4ae MSVCR80!terminate+0x4d

0012f84c 77e995f7 MSVCR80!__CxxUnhandledExceptionFilter+0x39

0012faa4 78138c06 kernel32!UnhandledExceptionFilter+0xac

0012fac4 004011f9 MSVCR80!_XcptFilter+0x6a

0012fad0 7813dfc4 win32!__tmainCRTStartup+0x137

0012fae4 7813bc8d MSVCR80!_EH4_CallFilterFunc+0x12

0012fb0c 00401754 MSVCR80!_except_handler4_common+0x8d

0012fb28 7c82eeb2 win32!_except_handler4+0x1f

0012fb4c 7c82ee84 ntdll!ExecuteHandler2+0x26

0012fbf4 7c82eda4 ntdll!ExecuteHandler+0x24

0012fed4 77e55dea ntdll!RtlRaiseException+0x3d

0012ff34 78158dc3 kernel32!RaiseException+0x53

0012ff6c 00401018 MSVCR80!_CxxThrowException+0x46

0012ff7c 004011d1 win32!main+0x18

0012ffc0 77e523cd win32!__tmainCRTStartup+0x10f

0012fff0 00000000 kernel32!BaseProcessStart+0x23

 

The difference is the kernel32!UnhandledExceptionFilter reenters for C++ EH. The 2nd call of kernel32!UnhandledExceptionFilter is invoked by MSVCR80!abort.

 

MSVCR80!abort builds Exception record on stack and set ExceptionRecord.ExceptionCode to STATUS_FATAL_APP_EXIT. After that it clears the CRT CxxUnhandledExceptionFilte and calls kernel32!UnhandledExceptionFilter with the new created exception record. It seems the new built ExceptionRecord hides the original C++ EH, and prevents the C++ EH to pass to drwtson32.

 

 

With above information, I tried VC6 and VS2003 with the same samples. The drwtson32 is even not triggered with the C++ EH sample. By understanding the logic of the CxxUnhandledExceptionFilter and abort function, the earlier version before VC8 terminates the process in CRT handler directly so there is no reentry of kernel32!UnhandledExceptionFilter to trigger the debugger set in AeDebug.

 

As a summary, drwtson32 is not a reliable tool to obtain the dump file. We can try the following alternative:

 

1.      Use IIS DebugDiag

2.      In AeDebug, change debugger setting to the following to use windbg instead:
C:/debuggers/windbg -p %ld -e %ld -c ".dump /mfh C:/myfile.dmp ;q"

3.      In Image File Execution Options setting, create a key with the target exe name. Change the debugger to the following:
C:/Debuggers/autodump.bat
Use the following as the bat file:
cscript.exe C:/Debuggers/adplus.vbs -crash -o C:/dumps -quiet -sc %1

### 三级标题:libMtcLoader fails to open .tp.settings errno 13 的问题分析与解决方案 在某些 Android 设备中,尤其是使用 MTK(联发科)平台的设备,可能会在系统日志中看到类似 `libMtcLoader fails to open .tp.settings errno 13` 的错误信息。该错误通常表示应用程序或系统模块在尝试加载 `.tp.settings` 文件时遇到权限问题[^1]。 #### 原因分析 错误码 `errno 13` 表示“Permission denied”(权限被拒绝),意味着 `libMtcLoader` 模块尝试访问 `.tp.settings` 文件时没有足够的权限。该文件通常用于配置热管理策略(thermal policy),其路径可能位于 `/system/etc/thermal/` 或 `/vendor/etc/thermal/` 目录下。由于 Android 系统对这些系统级配置文件的访问权限有严格限制,若调用进程没有适当的 SELinux 权限或文件权限设置不正确,就会导致该错误[^2]。 #### 解决方案 1. **检查文件权限** 确保 `.tp.settings` 文件的权限设置允许 `libMtcLoader` 所属的用户组进行读取操作。可以通过 `adb shell` 进入设备并使用 `ls -l` 查看文件权限: ```bash adb shell ls -l /system/etc/thermal/.tp.settings ``` 推荐的权限设置为 `644`,即: ```bash adb shell chmod 644 /system/etc/thermal/.tp.settings ``` 这样可以让系统以只读方式访问该文件[^3]。 2. **验证 SELinux 策略** 如果文件权限正确但问题仍然存在,则可能是 SELinux 策略限制了访问。可以通过临时将 SELinux 设置为宽容模式(permissive)来验证是否与此相关: ```bash adb shell setenforce 0 ``` 若问题在宽容模式下消失,则需要修改 SELinux 策略,为 `libMtcLoader` 添加对 `.tp.settings` 文件的访问权限。这通常涉及修改设备的 `sepolicy` 文件中的 `file_contexts` 和 `te` 策略文件[^4]。 3. **确认文件路径和存在性** 确保 `.tp.settings` 文件确实存在于预期路径中,并且路径没有拼写错误。某些设备可能使用不同的目录结构,例如 `/vendor/etc/thermal/` 而不是 `/system/etc/thermal/`。可以通过以下命令确认文件是否存在: ```bash adb shell find / -name ".tp.settings" 2>/dev/null ``` 4. **日志分析与调试** 使用 `logcat` 工具查看详细的错误日志,定位是哪个模块尝试访问该文件失败: ```bash adb logcat | grep "libMtcLoader" ``` 通过分析日志中的上下文信息,可以进一步判断是哪个服务或进程触发了此错误,并据此调整权限或路径配置[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值