If I run an executable that throws an exception ( built in debug ), I will receive an error dialog, saying something like "Debug assertion failed" and then some information about the exception. While this happens, the program's execution is suspended, until I choose one of "Abort", "Retry" or "Ignore" options.
The thing is, I run a lot of applications from a script, and if one of them throws an exception, it pauses my script until it's handled.
Is there someway to disable this exception handling mechanism?
EDIT: I remember reading about a registry key, a while ago, which would disable the error messages from appearing. Does anyone know about it?
If you can modify the source of the application(s), have a look at the _CrtSetReportMode function, eg:
_CrtSetReportMode(_CRT_ASSERT, 0);
See msdn for more.
If you can modify the source, the abort behavior (called by assert) needs to be modified to suppress the abort/retry/ignore dialog.
On abort, a crashdump will still be produced (by default) so you won't lose what is important.
Additionally, you can adjust the assert behavior to write to stderr only. This is NOT required if the abort behavior is adequate for what you want. Note: the _Crtxxx calls are only active in debug builds (/Zi).
A minimal change to disable the abort/retry/ignore. Uncomment the _Crt calls and include crtdbg.h to also modify the assert behavior in debug mode builds.
#include <stdlib.h>
//#include <crtdbg.h>
int main(int argc,char **argv);
int main(int argc,char **argv)
{
// ON assert, write to stderr.
//_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
//_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
// Suppress the abort message
_set_abort_behavior( 0, _WRITE_ABORT_MSG);
abort();
return 0;
}
msdn assert mode
Can you build your executables as release? If I recall, that should stop the assertion errors from appearing.
Related
Situation:
We have an MFC/C++ Visual Studio (2005) application consisting of a lot of executables and a lot of dlls, all using MFC and interconnected with DCOM. Some are running on a controller (w2012) which controls slave computers running on WES2009.
The problem:
For diagnostic purposes we are embedding minidumps in all of our processes. This mechanism works fine in all processes except for one: the GUI exe. All processes including the GUI make dmp files BUT the dmp file contents of the GUI seems to be different/wrong. When I intentionally crash our application with e.g. a null pointer dereference, all dmp files of all processes/dlls (except GUI) point to the cause (the null pointer dereference)! The dmp file of the GUI process is created and can be openend in Visual Studio but non of the threads point to the cause (the null pointer dereference). Also windbg does not find the cause! The strange thing is that when we manually use WriteStackDetails() to dump the callstack it returns the correct problematic line! So why can't MinidumpWriteDump() do the same for only this one process? What could be the discriminating factor? Anyone any idea?
What we tried:
We tried crashes in all other process and dlls and they all seem to work ok except the GUI process! Unicode / non-Unicode does not seem to matter. A seperate test application works well, also when I link our production code library which contains the UnhandledExceptionFilter() and MinidumpWriteDump(). Crashes in sub(-sub) dlls does not seem to matter. The project settings wrt exception handling appear to be all the same. Anyone any idea?
Some more info and remarks:
Our production code (controller and slaves) is running in separate virtual boxes for development purposes.
yes we understand that the minidump should ideally be created from another process (some example somewhere? wrt process querying and security?) but doing it in-process seems to work 'always ok' for now. So we accept the risk for now that it might hang in rare situations.
What I mean with the dmp file contents is different/wrong is the following:
For our non-GUI exe we get the following OK thread / callstack information:
0xC0000005: Access violation reading location 0x00000000.
Studio automatically opens the correct source and the "breakpoint" is set to the faulty line of code.
In the Call stack tab I see my own functions in my own dll which has caused the crash: my null pointer dereference.
In the Threads tab I also see my active thread and Location which points also to the faulty function which crashed.
So all is fine and usable in this situation! Super handy functionality!
For our GUI exe, which links to the same production library code wrt MinidumpWriteDump() and ExceptionHandlingFiler() code, we get the following NOK thread / callstack information:
Unhandled exception at 0x77d66e29 (ntdll.dll) in our_exe_pid_2816_tid_2820_crash.dmp: 0xC0150010: The activation context being deactivated is not active for the current thread of execution
Visual Studio 2005 does not show my faulty code as being the cause!
In the Call stack tab I don't see my own faulty function.
The Call stack tab shows that the problem is in ntdll.dll!RtlDeactivateActivationContextUnsafeFast()
The top most function call which is shown of our code is in a totally different gui helper dll, which is not related to my intentionally introduced crash!
The Threads tab also shows the same.
For both situations I use the same visual studio 2005 (running on w7) with the same settings for symbol paths!!! Also visual studio 2017 cannot analyze the 'wrong' dmp files. In between of both test above, there is no rebuild so no mismatch occurs between exe/dlls and pdbs. In one situation it works fine and in another not!?!
The stripped-down-to-essentials code we use is shown below
typedef BOOL (_stdcall *tMiniDumpWriteDump)(HANDLE hProcess, DWORD dwPid, HANDLE hFile,
MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
TCHAR CCrashReporter::s_szLogFileNameDmp[MAX_PATH];
CRITICAL_SECTION CCrashReporter::s_csGuard;
LPTOP_LEVEL_EXCEPTION_FILTER CCrashReporter::s_previousFilter = 0;
HMODULE CCrashReporter::s_hDbgHelp = 0;
tMiniDumpWriteDump CCrashReporter::s_fpMiniDumpWriteDump = 0;
CCrashReporter::CCrashReporter()
{
LoadDBGHELP();
s_previousFilter = ::SetUnhandledExceptionFilter(UnhandledExceptionFilter);
::InitializeCriticalSection(&s_csGuard);
}
CCrashReporter::~CCrashReporter()
{
::SetUnhandledExceptionFilter(s_previousFilter);
...
if (0 != s_hDbgHelp)
{
FreeLibrary(s_hDbgHelp);
}
::DeleteCriticalSection(&s_csGuard);
}
LONG WINAPI CCrashReporter::UnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
{
::EnterCriticalSection(&s_csGuard);
...
GenerateMinidump(pExceptionInfo, s_szLogFileNameDmp);
::LeaveCriticalSection(&s_csGuard);
return EXCEPTION_EXECUTE_HANDLER;
}
void CCrashReporter::LoadDBGHELP()
{
/* ... search for dbghelp.dll code ... */
s_hDbgHelp = ::LoadLibrary(strDBGHELP_FILENAME);
if (0 == s_hDbgHelp)
{
/* ... report error ... */
}
if (0 != s_hDbgHelp)
{
...
s_fpMiniDumpWriteDump = (tMiniDumpWriteDump)GetProcAddress(s_hDbgHelp, "MiniDumpWriteDump");
if (!s_fpMiniDumpWriteDump)
{
FreeLibrary(s_hDbgHelp);
}
else
{
/* ... log ok ... */
}
}
}
void CCrashReporter::GenerateMinidump(const PEXCEPTION_POINTERS pExceptionInfo,
LPCTSTR pszLogFileNameDmp)
{
HANDLE hReportFileDmp(::CreateFile(pszLogFileNameDmp, GENERIC_WRITE, 0, 0,
CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0));
if (INVALID_HANDLE_VALUE != hReportFileDmp)
{
MINIDUMP_EXCEPTION_INFORMATION stMDEI;
stMDEI.ThreadId = ::GetCurrentThreadId();
stMDEI.ExceptionPointers = pExceptionInfo;
stMDEI.ClientPointers = TRUE;
if(!s_fpMiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(),
hReportFileDmp, MiniDumpWithIndirectlyReferencedMemory,
&stMDEI, 0, 0))
{
/* ... report error ...*/
}
else
{
/* ... report ok ... */
}
::CloseHandle(hReportFileDmp);
}
else
{
/* ... report error ...*/
}
}
For testing purposes only, I'm including a function to intentionally crash my app (testing my app's handling of unintentional crashes). To do so, I'm using:
strcpy(0, "crash");
Of course, when doing analysis of my code, Xcode reports the logic error Null pointer argument in call to string copy function. I've tried wrapping the offending code like so:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
strcpy(0, "crash");
#pragma clang diagnostic pop
But Xcode (v9.2 (9C40b)) still complains (this isn't a warning, it's a logic error, I understand). Is there some other way to keep Xcode/clang from flagging this code? Is there some better way to induce a crash that can be protected from Xcode/clang analysis error?
This worked for me (no need to wrap in warning suppressions). It passes Xcode/clang's analysis and still results in the crash I want:
char *x = (char *)#"0".integerValue; strcpy(x, "crash");
How about volatile char* x=0; strcpy(x, "crash")
This'll work because the compiler isn't allowed to assume that x when read will be any value; meaning any checks that it might have hard coded should be ignored.
It seems to me that the best way to defeat static analysis is to do something dynamic. Objective-C, by its very nature, has lots of options for that, since the compiler can't guarantee a 1-to-1 correspondence between a message send and a method.
The simplest thing to do is probably to trigger an indexing error:
[#"" characterAtIndex:0]; // or
[#[] objectAtIndex:0];
Even if the analyzer knew that the default implementations of those methods raised an exception for out-of-bounds access, it can't know that you haven't swapped them out at runtime for an implementation that handles the problem gracefully.
#include <windows.h>
long __stdcall callback(_EXCEPTION_POINTERS* excp)
{
MessageBox(0, "Error", "error", MB_OK);
return EXCEPTION_EXECUTE_HANDLER;
}
int main(int argc, char* argv[])
{
SetUnhandledExceptionFilter(callback);
int * p;
free(p); //to crash
return 0;
}
When I use SetUnhandledExceptionFilter to catch the error,it does not work.My IDE is vs 2013 , x64 system and program. I tried both debug and release ,all failed.
If it was abandoned,how I can get crash dump in the program?
In order to trigger the callback, all of the following conditions must be met:
It must be a debug build, because the invalid free() doesn't cause an exception in a release build. (It might or might not indirectly cause an exception in a larger program, but in the code as posted it does not.)
You must be running the executable without the debugger, because unhandled exception filters are ignored if a debugger is present.
You must select the "Ignore" option when presented with the Debug Error window warning you that p is being used without being initialized.
I'm not sure what it is that you're actually trying to achieve here, but this is probably not the right way to go about it.
Below is a code snippet where I deliberately cause 2 NullPointerException. The first one is handled. Whereas the second one goes unhandled. I want to create a crash dump on the second exception when a crash would occur.
int* nullPtr = NULL;
try{
x = *nullPtr;
}
catch(...) {
QLOG_WARNING0(QTEXT("catching 1st null ptr exception."));
}
y = *nullPtr;
This does crash the process but the dump is not generated using -e option only.
What options should I use to get the dump?
Or is there a way I could achieve this with debugDiag tool? If so, how?
This is only a sample code. The actual use case I am debugging has a process crashing but I am unable to take dumps for the crash. There are valid handled exceptions where the dump is getting triggerred in case I use the first chance option( - e 1). This is causing procdump to exit before the actual crash occurs.
“No I am open to any other tool.”
Per your comment, there are other ways to trap a dump file. In my answer to Getting detailed crash dumps from a hooked exe,
you’ll see that you can set some registry key settings to trap the dump from an unhandled exception. The settings assume you have Windows Error Reporting enabled. I’ve gone so far as to incorporate those settings into a small utility program that my company uses when debugging difficult customer crashes.
I have an example of a strcpy command that seems to be a risk of a buffer overflow, but PVS-Studio doesn’t raise a warning. In my example, strcpy is used to copy a command line argument into a buffer, without checking the size of the command line argument. This could result in a buffer overflow if the argument exceeds the size of the buffer.
Code example:
char carg1[13];
int main(int argc, char* argv[])
{
// Get name from the 1st command line arg
strcpy(carg1, argv[1]);
…
}
The size of argv[1] isn't checked before being coping into carg1. Shouldn’t this raise a warning?
It's theoretically impossible to build a perfect static analysis tool (this follows from results like the undecidability of the halting problem). As a result, all static analysis tools are at best heuristics that can try to detect certain classes of errors, and even then can't necessarily detect all of those errors.
So yes, the code you've got above looks like it has a potential buffer overflow. I honestly don't know why this particular tool can't detect the error, but my guess is that the internal heuristics the analyzer uses for some reason is failing to detect it.
Hope this helps!
There are 3 facts:
1) If you use Visual C++ compiler then you will receive compiler warnings 4996.
1>robust.cpp(529): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\string.h(110) : see declaration of 'strcpy'
2) PVS-Studio initially worked with Visual Studio only.
3) PVS-Studio policy is to implement diagnostic rules which are not duplicate compiler warnings.
So it is seems a logical that PVS doesn't check the case which are already was checked by Microsoft compiler for a long time already (from VS2005).
Updated:
Finally PVS implemented such diagnostic rule:
https://www.viva64.com/en/w/V755/print/