#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.
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 ...*/
}
}
I am looking at the Linux kernel flow, where I came across early_printk,
which is used for printk before console is initialized.
In my case early_printk is not enabled and still I am getting prints with printk before console_init.
From where i am getting these prints?
If you see the kernel source code as below, even though early_printk is disabled, kernel message needs to prints in scenario like panic etc.
#ifdef CONFIG_EARLY_PRINTK
extern asmlinkage __printf(1, 2)
void early_printk(const char *fmt, ...);
#else
static inline __printf(1, 2) __cold
void early_printk(const char *s, ...) { }
From the above, its enable or not early_printk() is called and in disable case it will be called if any early_panic() is there.
early_panic() means if kernel is trying to recover some problem like below and if not then panic() will happen and it will die.
[40462.661285] Attribute myarray: Invalid permissions 0700
|
here I tried to give permission to `variable` to verify whether `panic` happens or not.
I am using Visual studio 2013 always encountered a break point when compiling my code in debug mode.
Before this post I gone through this and this.
I went through [DEBUG-> Windows-> Breakpoints] there is no break point available to delete any.
Below screenshot for how my exe triggering breakpoint at time of compilation. Yes, my project contains numerous libraries and this break point triggering only to library files. Could anyone help me to fix it, i googled a lot but can't?
Here is my Call stack copy:
ntdll.dll!770cfe2c() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
[External Code]
DemoProj.exe!CryptoPP::MessageQueue::TransferTo2(CryptoPP::BufferedTransformation & target, unsigned __int64 & transferBytes, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & channel, bool blocking) Line 27 C++
DemoProj.exe!CryptoPP::BufferedTransformation::Get(unsigned char * outString, unsigned int getMax) Line 420 C++
When i debugging my code getting a error i.g "UMEngx86.dll'. Cannot find or open the PDB file."
'DemoProj.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. Symbols loaded.
'DemoProj.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sysfer.dll'. Cannot find or open the PDB file.
'DemoProj.exe' (Win32): Loaded 'C:\ProgramData\Symantec\Symantec Endpoint Protection\12.1.4112.4156.105\Data\Definitions\BASHDefs\20160125.011\UMEngx86.dll'. Cannot find or open the PDB file.
'DemoProj.exe' (Win32): Loaded 'C:\~…\release\log4cplus.dll'. Module was built without symbols.
I also read this document about this issue. Still need help from export.
Finally, i able to solve my won problem.
What was the problem?
A: It was a heap memory corruption, so Heap manager thrown a exception by triggering a automatic break point.
Where you did mistake?
Ans: I am explaining my mistake with simple example;
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
char *buffer = "Simple Heap Error Demo";
int len = strlen(buffer);
char *plaintext = new char[len]; //Here i mistaken
/*It should be char *plaintext = new char[len + 1]; because i need one more memory cell for NULL character, that i forgotten and later i am trying to delete [] palintext. */
memcpy(plaintext, buffer, len);
plaintext[len] = '\0';
cout << "\nplaintext: " << plaintext;
if (plaintext != NULL);
delete[] plaintext; //Exception thrown here
system("pause");
//cout << "\nplaintext: " << plaintext;
return 0;
}
How you solved your problem?
Ans: First i neatly debug my project using WinDbg found where exactly heap corruption exception happening. Then i wrote a simple separate program related to same scenario and able to fix my problem.
A special thanks to Steve who helped me to resolve my issue.
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.
On my Windows 7 box, this simple program causes the memory use of the application to creep up continuously, with no upper bound. I've stripped out everything non-essential, and it seems clear that the culprit is the Microsoft Iphlpapi function "GetIpAddrTable()". On each call, it leaks some memory. In a loop (e.g. checking for changes to the network interface list), it is unsustainable. There seems to be no async notification API which could do this job, so now I'm faced with possibly having to isolate this logic into a separate process and recycle the process periodically -- an ugly solution.
Any ideas?
// IphlpLeak.cpp - demonstrates that GetIpAddrTable leaks memory internally: run this and watch
// the memory use of the app climb up continuously with no upper bound.
#include <stdio.h>
#include <windows.h>
#include <assert.h>
#include <Iphlpapi.h>
#pragma comment(lib,"Iphlpapi.lib")
void testLeak() {
static unsigned char buf[16384];
DWORD dwSize(sizeof(buf));
if (GetIpAddrTable((PMIB_IPADDRTABLE)buf, &dwSize, false) == ERROR_INSUFFICIENT_BUFFER)
{
assert(0); // we never hit this branch.
return;
}
}
int main(int argc, char* argv[]) {
for ( int i = 0; true; i++ ) {
testLeak();
printf("i=%d\n",i);
Sleep(1000);
}
return 0;
}
#Stabledog:
I've ran your example, unmodified, for 24 hours but did not observe that the program's Commit Size increased indefinitely. It always stayed below 1024 kilobyte. This was on Windows 7 (32-bit, and without Service Pack 1).
Just for the sake of completeness, what happens to memory usage if you comment out the entire if block and the sleep? If there's no leak there, then I would suggest you're correct as to what's causing it.
Worst case, report it to MS and see if they can fix it - you have a nice simple test case to work from which is more than what I see in most bug reports.
Another thing you may want to try is to check the error code against NO_ERROR rather than a specific error condition. If you get back a different error than ERROR_INSUFFICIENT_BUFFER, there may be a leak for that:
DWORD dwRetVal = GetIpAddrTable((PMIB_IPADDRTABLE)buf, &dwSize, false);
if (dwRetVal != NO_ERROR) {
printf ("ERROR: %d\n", dwRetVal);
}
I've been all over this issue now: it appears that there is no acknowledgment from Microsoft on the matter, but even a trivial application grows without bounds on Windows 7 (not XP, though) when calling any of the APIs which retrieve the local IP addresses.
So the way I solved it -- for now -- was to launch a separate instance of my app with a special command-line switch that tells it "retrieve the IP addresses and print them to stdout". I scrape stdout in the parent app, the child exits and the leak problem is resolved.
But it wins "dang ugly solution to an annoying problem", at best.