jirentabu / crashrpt

Automatically exported from code.google.com/p/crashrpt
0 stars 0 forks source link

Exception handling problems in WTLDemo #180

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I have a couple of questions though: after I compiled it from source and played 
with WTLDemo (tested only main thread), it either doesn't detect an exceptional 
situation, or the generated minidump doesn't contain any useful clues as to 
where to look for a bug. Here is a list of my tests:

=== not working as expected ===

(1) buffer overrun - crashes with "CrashRptTest module stopped working" 
message. Then there is a chance to debug, the next message I see is this one: 
"A buffer overrun has occurred in WTLDemo.exe which has corrupted the program's 
internal state. Press Break to debug the program or Continue to terminate the 
program." I press break and observe the following stack:

CrashRpt1400.dll!test_buffer_overrun(const char * str=0x31206e61) Line 794 + 
0xd bytes   C++
68742072() 
WTLDemo.exe!CMainDlg::DoCrash() Line 176    C++
WTLDemo.exe!CMainDlg::OnOK(unsigned short __formal=2466, unsigned short 
__formal=2466, unsigned short __formal=2466, unsigned short __formal=2466) Line 
143 C++
WTLDemo.exe!ATL::CDialogImplBaseT<ATL::CWindow>::DialogProc(HWND__ * 
hWnd=0x00000000, unsigned int uMsg=273, unsigned int wParam=1, long 
lParam=5769864) Line 2306   C++

Everything looks correctly caught, except for it didn't happen within CrashRpt 
module. I recall reading somewhere (big chances - in the documentation) that 
security situations are impossible to handle in anything other than DrWatson. 
Is this the case, or an issue with CrashRpt?

(2) SIGFPE - "Error creating exception situation", "Unspecified error", 
continues;

(3) throw C++ typed exception - Runtime error, the application requested the 
runtime to terminate, no option to debug

(4) manual report - works fine, but the resulting minidump is of 0 bytes size.

=== stack trace not quite useful ===

(5) pure virtual call - here is the stack trace:

CrashRpt1400.dll!CCrashHandler::GenerateErrorReport(tagCR_EXCEPTION_INFO * 
pExceptionInfo=0x00daf2f0) Line 1210    C++
CrashRpt1400.dll!CCrashHandler::PureCallHandler() Line 1828 C++
msvcr90.dll!73f319e9() 
[Frames below may be incorrect and/or missing, no symbols loaded for 
msvcr90.dll]    
uxtheme.dll!7374a8e7() 
uxtheme.dll!73741d34() 
kernel32.dll!748514dd() 
comctl32.dll!71bc4663() 
comctl32.dll!71bc44ed() 
KERNELBASE.dll!761d8720() 
user32.dll!75ae62fa() 
user32.dll!75ae6d3a() 
user32.dll!75ae6ce9() 
user32.dll!75ae80a9() 
user32.dll!75b0c81f() 
WTLDemo.exe!CMainDlg::PreTranslateMessage(tagMSG * pMsg=0x00dafc0c) Line 28 C++
WTLDemo.exe!WTL::CMessageLoop::PreTranslateMessage(tagMSG * pMsg=0x00dafc0c) 
Line 1207 + 0xb bytes   C++
WTLDemo.exe!WTL::CMessageLoop::Run() Line 1166 + 0x9 bytes  C++
WTLDemo.exe!Run(wchar_t * __formal=0x00142ca0, int nCmdShow=1) Line 76  C++
WTLDemo.exe!wWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * 
__formal=0x00000000, wchar_t * lpstrCmdLine=0x00142ca0, int nCmdShow=1) Line 
209 + 0xd bytes C++
WTLDemo.exe!__tmainCRTStartup() Line 578 + 0x1c bytes   C

Looks like the PreTranslateMessage is not exacrtly the place where pure virtual 
call happened. Is it by windows design? Can it be improved?

(The XML from this crash report is attached so that you can see my system 
configuration).

(6) new operator fault - the condition takes very long to detect, it doesn't 
begin until I drag-drop the application window. Then a stacktrace is generated. 
Although better than in pure virtual call situation, it is still not very 
useful:

CrashRpt1400.dll!CCrashHandler::GenerateErrorReport(tagCR_EXCEPTION_INFO * 
pExceptionInfo=0x00daf2b0) Line 1210    C++
CrashRpt1400.dll!CCrashHandler::NewHandler(unsigned int __formal=60) Line 
1959    C++
msvcr90.dll!73ee1b1e() 
[Frames below may be incorrect and/or missing, no symbols loaded for 
msvcr90.dll]    
msvcr90.dll!73f23dd1() 
msvcr90.dll!73f23eb8() 
CrashRpt1400.dll!crSetErrorMsg(wchar_t * pszErrorMsg=0x10012bf0) Line 648   C++
0000003c()  
comctl32.dll!71bb67e0() 
WTLDemo.exe!CMainDlg::DoCrash() Line 166    C++
WTLDemo.exe!CMainDlg::OnOK(unsigned short __formal=1310, unsigned short 
__formal=1310, unsigned short __formal=1310, unsigned short __formal=1310) Line 
143 C++
WTLDemo.exe!ATL::CDialogImplBaseT<ATL::CWindow>::DialogProc(HWND__ * 
hWnd=0x00000000, unsigned int uMsg=273, unsigned int wParam=1, long 
lParam=5046332) Line 2306   C++

The DoCrash frame points at line "  if(nThread==0) // The main thread", which I 
guess is quite far from the exception point. Can this be improved?

(7) SIGABRT - the stack contains only the following 2 frames from the handler, 
but all frames below are in msvcrt, user32 and so on. Is there a way to handle 
it closer to the actual signal?

CrashRpt1400.dll!CCrashHandler::GenerateErrorReport(tagCR_EXCEPTION_INFO * 
pExceptionInfo=0x00daef70) Line 1210    C++
CrashRpt1400.dll!CCrashHandler::SigabrtHandler(int __formal=22) Line 1999   C++

(8) SIGINT, SIGTERM - the stack is the same as in (5) - the last sane frame is  
PreTranslateMessage

Original issue reported on code.google.com by zexspect...@gmail.com on 20 Dec 2012 at 6:54

GoogleCodeExporter commented 9 years ago
I double-checked the C++ exceptions test on 2 systems and here is an update:
 - on a machine which builds with VS2008, the C++ typed exception is not intercepted by crashrpt
 - on a machine with Windows SDK 7.1 (I guess, the compiler is the same as in VS2010), crashrpt handles the situation.

Original comment by anton.ob...@gmail.com on 20 Dec 2012 at 12:49

GoogleCodeExporter commented 9 years ago
Related to VS2008. Did you generate the solution file with CMake? If so, there 
may be a build misconfiguration in CMake-generated projects. I'll check this 
with VS2008 Express.

Original comment by zexspect...@gmail.com on 20 Dec 2012 at 3:48

GoogleCodeExporter commented 9 years ago
No, I generate NMakeFiles with CMake (cause I have to stick to building from 
within Windows SDK Command prompt), and here is how I invoke build:

cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE:STRING=Release 
-DCMAKE_CXX_FLAGS:STRING="/DWIN32 /D_WINDOWS /DUNICODE /W3 /Zm1000 /GR /EHsc 
/I%ATL_INC_BACKSLASHES%" -DCMAKE_CXX_FLAGS_RELEASE:STRING="/nologo /W3 /MD 
/EHsc /Zi /O2 /Oy- /Ob1 /DNDEBUG" -DCMAKE_C_FLAGS:STRING="/DWIN32 /D_WINDOWS 
/DUNICODE /W3 /Zm1000 /I%ATL_INC_BACKSLASHES%" 
-DCMAKE_C_FLAGS_RELEASE:STRING="/nologo /W3 /MD /EHsc /Zi /O2 /Oy- /Ob1 
/DNDEBUG" -DCMAKE_EXE_LINKER_FLAGS_RELEASE:STRING="/DEBUG /INCREMENTAL:YES" 
-DCMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING="/DEBUG /INCREMENTAL:YES" 
-DCMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING="/DEBUG /INCREMENTAL:YES" .

nmake ConsoleDemo WTLDemo CrashRpt CrashSender Tests

Original comment by anton.ob...@gmail.com on 20 Dec 2012 at 4:28

GoogleCodeExporter commented 9 years ago
I compiled WTLDemo in VC++ 2008 Express, and it could not even start, and I 
could not even debug it. I think, this is probably some strange error in VC 
compiler.

Then I compiled WTLDemo in VC++ 2005 Express, and it ran OK. I chose 'throw C++ 
exception' and crashed the app, then opened the minidump file. The stack trace 
was rather inaccurate:

    KERNELBASE.dll!7575c41f()   
    [Указанные ниже фреймы могут быть неверны и (или) отсутствовать, символы для KERNELBASE.dll не загружены]  
    KERNELBASE.dll!7575c41f()   
    comctl32.dll!74174663()     
    comctl32.dll!741744ed()     
    user32.dll!763972b9()   
    user32.dll!763962fa()   
    user32.dll!76396d3a()   
    user32.dll!76396ce9()   
    user32.dll!763977c4()   
    user32.dll!7639788a()   
    user32.dll!763bc81f()   
>   WTLDemo.exe!CMainDlg::PreTranslateMessage(tagMSG * pMsg)  Строка 28   C++
    WTLDemo.exe!WTL::CMessageLoop::PreTranslateMessage(tagMSG * pMsg)  Строка 1207 + 0xb байт C++
    WTLDemo.exe!WTL::CMessageLoop::Run()  Строка 1166 + 0x7 байт  C++
    WTLDemo.exe!Run(wchar_t * __formal, int nCmdShow)  Строка 76  C++
    WTLDemo.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * __formal, wchar_t * lpstrCmdLine, int nCmdShow)  Строка 197 + 0xb байт    C++
    WTLDemo.exe!__tmainCRTStartup()  Строка 547 + 0x1c байт   C
    kernel32.dll!762833aa()     
    ntdll.dll!77b79ef2()    
    ntdll.dll!77b79ec5()    

But I don't know how to improve stack trace accuracy here. 

Then I compiled WTLDemo in VS 2010, and it ran OK. I chose 'throw C++ 
exception' and crashed the app, then opened the minidump file. The stack trace 
was the same - very inaccurate.

So, I have no ideas on how to improve its accuracy.

Original comment by zexspect...@gmail.com on 21 Dec 2012 at 9:35

GoogleCodeExporter commented 9 years ago
Related to inaccurate stack - I remember it was better in previous versions of 
CrashRpt. I need to look at the code responsible for retrieval of exception 
pointers (CCrashHandler::GetExceptionPointers() class member). I remember I 
refactored this method some time ago, and maybe something is now wrong with it. 

Original comment by zexspect...@gmail.com on 21 Dec 2012 at 10:24

GoogleCodeExporter commented 9 years ago
Yes, there was a bug in CCrashHandler class. I tried to fix it. You can check 
out the latest code from trunk. Now the stack traces should be more accurate. 
Please let me know if this helped you.

And I need to look at SIGFPE problem another time.

Original comment by zexspect...@gmail.com on 21 Dec 2012 at 4:18

GoogleCodeExporter commented 9 years ago
I checked with top of trunk (rev 1478), the manual dump works good now, but 
unfortunately the virtual call, SIGINT and SIGTERM still expose useless stack 
trace (last known frame is PreTranslateMessage). Just to make sure you can 
reproduce, I compiled with VS2008 x86 target.

Original comment by anton.ob...@gmail.com on 22 Dec 2012 at 2:27

GoogleCodeExporter commented 9 years ago
I have an idea of how to improve this. You should enable symbol file generation 
for CrashRpt.dll and save that PDB file together with symbol files for your 
modules. CrashRpt code uses some optimizations, and without symbols you will 
get useless stack trace. I'll disable optimizations in the next release.

Original comment by zexspect...@gmail.com on 22 Dec 2012 at 2:30

GoogleCodeExporter commented 9 years ago
I already do that by overriding compiler flags, here they are:
/nologo /W3 /MD /EHsc /Zi /O2 /Oy- /Ob1 /DNDEBUG
And linker flags:
/DEBUG /INCREMENTAL:YES

So I have PDB files for all CrashRpt modules, and it is compiled with /Oy- 
(disables frame pointer omission). Can you suggest an improvement to the CL/LD 
options?

Thanks,
Anton

Original comment by anton.ob...@gmail.com on 22 Dec 2012 at 3:08

GoogleCodeExporter commented 9 years ago
I'm suspisious about your /O2 flag. Doesn't it define an optimization level?

I tested WTLDemo with 'pure virtual call' exception type (VS2010), and its 
stack trace was as accurate as it should be. Here is the command line for the 
compiler:

/I"D:\Projects\CrashRpt\trunk\include" 
/I"D:\Projects\CrashRpt\trunk\reporting\crashsender" 
/I"D:\Projects\CrashRpt\trunk\thirdparty\tinyxml" 
/I"D:\Projects\CrashRpt\trunk\thirdparty\zlib" 
/I"D:\Projects\CrashRpt\trunk\thirdparty\libpng" 
/I"D:\Projects\CrashRpt\trunk\thirdparty\wtl" /Zi /nologo /W4 /WX- /MP /O1 /Ob1 
/Os /Oy- /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "STRICT" /D 
"CRASHRPT_EXPORTS" /D "_VC80_UPGRADE=0x0600" /D "_WINDLL" /D "_UNICODE" /D 
"UNICODE" /GF /Gm- /EHsc /MD /GS /Gy /fp:precise /fp:except /Zc:wchar_t 
/Zc:forScope /Yu"stdafx.h" /Fp"Release\CrashRpt1400.pch" /Fa"Release\" 
/Fo"Release\" /Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue 

I'll check CMake file to ensure it defines the correct compiler flags.

Original comment by zexspect...@gmail.com on 24 Dec 2012 at 2:52

GoogleCodeExporter commented 9 years ago
I checked on VS2010, Windows 7 x32 - works like charm =)
On VS2008 and Win7 x64 the stack is wrong pretty persistent. Could it be 
related to the callbacks issue with exceptions not being propagated across WOW 
subsystem?
Checking other configurations in the meantime..

Original comment by anton.ob...@gmail.com on 28 Dec 2012 at 6:51

GoogleCodeExporter commented 9 years ago
I extended unit tests to check if different exceptions are caught and if the 
stack trace can be recovered. Tested is VS2005 and VS2010 (I don't have VS2008).

I also modified the VS2010 solution's projects and CMakeLists.txt to disable 
optimizations. This should resolve the problem of floating point exceptions 
(SIGFPE), because the code responsible for division by zero was just stripped 
by optimizations and never executed at all.

Please let me know if this works for you.

Original comment by zexspect...@gmail.com on 6 Jan 2013 at 3:10

GoogleCodeExporter commented 9 years ago
This issue was closed by revision r1493.

Original comment by zexspect...@gmail.com on 6 Jan 2013 at 3:11