I have some image processing code that runs on a background thread and updates an Image control on the UI thread when it's done processing using Dispatcher.BeginInvoke(). When I'm running my application outside of the debugger, it crashes quite often. As soon as I run it in the debugger, I can't get it to happen at all. Apparently the timing difference is enough to make my life miserable right now ;-)
I've tried putting try/catch blocks around any code that seems relevant and logging any errors that come up, but to no avail - it somehow keeps slipping past me, and I'm not sure where else to look.
My hope for using the debugger was to set the debugger's exception catching behavior to break whenever any exception was thrown, but since I can't get the exception to happen while debugging, I can't find out where my code is throwing.
I can attach to my crashed process (since it stays on screen, just is completely unresponsive), pause the debugger, and see where each thread is in the code, but that doesn't really help me - I have no idea what the actual exception being thrown is.
Any suggestions on how to proceed?
Edit:
I've been using System.Diagnostics.Trace.WriteLine() with DbgView in as many places as I can think. I can track down where it appears the exception is occurring, I can't find out what the exception is, which is what is important.
I've used WinDBG+SOS before, to track down memory leaks, but not to track down hard-to-find-exceptions. Can anyone suggest resources for using WinDBG+SOS in this capacity?
With only few exceptions every BeginInvoke should have a corresponding EndInvoke counterpart (see here for more details why, one exception is e.g. Control.BeginInvoke).
A missing EndInvoke might be the reason that an exception is not caught by the main thread and your application terminates.
Since in your special case you are dealing with Dispatcher (which does not implement EndInvoke) you will have to handle the Dispatcher.UnhandledException event to catch any exception thrown during execution of a delegate.
By the way, a good tool to monitor the System.Diagnostics.Trace messages is DbgView from Sysinternals.
How can you be sure it's an exception, when you've never caught it?
Also, rather than placing try/catch blocks all over the place, place them at boundaries, especially at thread boundaries. Put them around any ThreadStart methods or other code invoked by BeginInvoke, or callback methods, etc.
Can you put one try/catch in the static Main called on application start? So when app crash you can output stacktrace and exception info somewhere.
Related
I need to get the code coverage information for a amount of C programs. I only need to know whether or not each line is executed. However, some of them will never end for the sake of infinite loops. The most of tools, e.g. like gcov, llvm-cov, which could get the information for the program only after it ends.
I set a time limitation for all the programs. If it dosen't end when its exection time is beyound the limitation, its process will be killed. However, when its process was killed, all the information stored in the memory is cleaned. So I can't get the code coverage information for those programs. How can I do that?
A simple solution would be to add a litle timer interrupt inside your program that will raise an exception after a few seconds of "bad behaviour" and cause the program to terminate nicely.
When searching and probing in the temporary fashion you seem to be after, it is completely legit to "hack it" as long as you remove the hack immediately you found the error..
I am trying to write a small app that debugs another process by its ID and monitors the app until it crashes.
For now I've written a small code, most of it is from the MS example for writing a debugger.
My target application never passes the if(!de.u.Exception.dwFirstChance), even after the target has crashed.
I am able to see the exceptions coming if I put a bp on if(!de.u.Exception.dwFirstChance), but no exception meets the condition.
P.S : Too many edits :/
#include "stdafx.h"
#include <windows.foundation.diagnostics.h>
#include <debugapi.h>
#include <ntstatus.h>
DEBUG_EVENT de;
int _tmain(int pid)
{
DebugActiveProcess( pid);
while (true)
{
int a;
if (WaitForDebugEvent (&de, (DWORD)1000))
{
if (de.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
{
if(!de.u.Exception.dwFirstChance)
int excep = de.u.Exception.ExceptionRecord.ExceptionCode;
}
}
ContinueDebugEvent ( de.dwProcessId,
de.dwThreadId,
DBG_CONTINUE);
}
}
The article "Writing a Plug-in for Sysinternals ProcDump v4.0" indicates in the pseudo-code that the dump of a monitored process is generated when (and only when) a "Second Chance Exception" occurs.
// (extract altered for brevity)
Else "Second Chance Exception"
WriteDump(..)
Done = True
And "Writing a basic Windows debugger" indicates that EXCEPTION_DEBUGINFO.dwFirstChance, with a guard for STATUS_BREAKPOINT/EXCEPTION_BREAKPOINT can be used to detect this case.
"First and second chance exception handling" (KB105676) explains the difference between the exception chance types:
However, if the application is being debugged, the debugger sees all [first chance] exceptions before the program does. This is the distinction between the first and second chance exception: the debugger gets the first chance to see the exception (hence the name).
It is these First Chance Exceptions ("managed" or not) which are being detected, but they are almost all recoverable - i.e. they are caught by the application/run-time code and dealt with appropriately.
If the debugger allows the program execution to continue and does not handle the exception, the program will see the exception as usual. If the program does not handle the exception, the debugger gets a second chance to see the exception. In this latter case, the program normally would crash if the debugger were not present.
Thus, procdump likely generates the dump for a second chance exception with the assumption that any process-fatal exception will not be suppressed (by another debugger, as the program gave up its chance).
(EXIT_PROCESS_DEBUG_EVENT occurs after the process is terminated and is thus too late to generate an appropriate dump, although it does signal to end monitoring.)
YMMV: All information/observations comes from the articles and resources listed, without actual experience in usage of such techniques.
There is a previous question/answer about the single step exception: What is a single step exception?
Every exception you enumerated will crash your application if unhandled. There is a lot of information on the web about each.
Simple newbie advice: it is very unlikely that you are the first person ever to encounter a problem or wonder what something means. Google is a more appropriate tool for things like this. Google first, StackExchange if you can't find the answer.
Can you detect whether or not a debugger is attached to your native Windows process by using a high precision timer to time how long it takes to divide an integer by zero?
The rationale is that if no debugger is attached, you get a hard fault, which is handled by hardware and is very fast. If a debugger is attached, you instead get a soft fault, which is percolated up to the OS and eventually the debugger. This is relatively slow.
Since there is absolutely nothing you can do to prevent a determined person from reverse engineering your code, no clever approach you find will be significantly better than calling IsDebuggerPresent()
No. A sufficiently determined attacker would simply host your process in a VM and break in that way.
Besides, you don't need to attach a debugger to attack a program: grabbing a minidump will let an adversary inspect the memory state offline, or using process explorer you can inspect open handles to determine what files are vulnerable.
If you were going to use an exception to determine whether a naive debugger were attached, I'd personally use INT_MIN/-1 to trigger an integer overflow exception. Most don't know about that one.
most debuggers used by reverse engineers come with methods to affect (remove) 99% of the marks left by debuggers, most of these debuggers provided exception filtering, meaning the speed difference would be undetectable.
its more productive to prevent the debugger attaching in the first place, but in the long run you'll never come out ahead unless you make the required effort investment unfeasable.
I have a program which produces a fatal error with a testcase, and I can locate the problem by reading the log and the stack trace of the fatal - it turns out that there is a read operation upon a null pointer.
But when I try to attach gdb to it and set a breakpoint around the suspicious code, the null pointer just cannot be observed! The program works smoothly without any error.
This is a single-process, single-thread program, I didn't experience this kind of thing before. Can anyone give me some comments? Thanks.
Appended: I also tried to call pause() syscall before the fatal-trigger code, and expected to make the program sleep before fatal point and then attach the gdb on it on-the-fly, sadly, no fatal occurred.
It's only guesswork without looking at the code, but debuggers sometimes do this:
They initialize certain stuff for you
The timing of the operations is changed
I don't have a quote on GDB, but I do have one on valgrind (granted the two do wildly different things..)
My program crashes normally, but doesn't under Valgrind, or vice versa. What's happening?
When a program runs under Valgrind,
its environment is slightly different
to when it runs natively. For example,
the memory layout is different, and
the way that threads are scheduled is
different.
Same would go for GDB.
Most of the time this doesn't make any
difference, but it can, particularly
if your program is buggy.
So the true problem is likely in your program.
There can be several things happening.. The timing of the application can be changed, so if it's a multi threaded application it is possible that you for example first set the ready flag and then copy the data into the buffer, without debugger attached the other thread might access the buffer before the buffer is filled or some pointer is set.
It's could also be possible that some application has anti-debug functionality. Maybe the piece of code is never touched when running inside a debugger.
One way to analyze it is with a core dump. Which you can create by ulimit -c unlimited then start the application and when the core is dumped you could load it into gdb with gdb ./application ./core You can find a useful write-up here: http://www.ffnn.nl/pages/articles/linux/gdb-gnu-debugger-intro.php
If it is an invalid read on a pointer, then unpredictable behaviour is possible. Since you already know what is causing the fault, you should get rid of it asap. In general, expect the unexpected when dealing with faulty pointer operations.
Sometimes in execution I get this error message in VS2010 when trying to free memory:
Windows has triggered a breakpoint in [APPNAME].exe.
This may be due to a corruption of the heap, which indicates a bug in [APPNAME].exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while [APPNAME].exe has focus.
The output window may have more diagnostic information.
Wich means something is wrong with heap or pointer.
My issue is that this error crashes my app when it is built as a release.
Also this is just a module of bigger application and when this crashes everithing goes down.
I would like to be able to handle this error.
From msdn on "free":
If an error occurs in freeing the memory, errno is set with information from the operating system on the nature of the failure. For more information, see errno, _doserrno, _sys_errlist, and _sys_nerr.
There is a errno_t _get_errno( int * pValue ); function that returns error code.
If I press continue on the error msg shown above this function returns error code.
Using this code I can detect error, create call stack and exit my function softly.
Is there any compiler switch or something to prevent aplication from crashing when free fails and allow me to exit it my way??
If the heap is corrupted, all bets are off. Memory allocations may fail (unless they're on the stack), they might return pointers to wacky areas, and even existing stuff on the heap could be mangled beyond recognition. In such cases, you're actually better off crashing, as any action you take (even trying to gracefully exit) could just make things much worse.
Find the code that's mangling stuff on the heap, and fix or remove it.
Theoretically you try to prevent your app from crashing using SEH.
AFAIK "debug breakpoint" is a sort of a SEH exception, which can be handled.
__try {
// do something here
} __except(EXCEPTION_EXECUTE_HANDLER) {
}
The above __try/__except block will catch all the exceptions (both C++ and SEH).
HOWEVER
I believe you should not do this. Heap corruption, as well as any other invalid memory access - is an bug Once this happens - the damage is usually unrecoverable. You may prevent the crash (hopefully), but you can not guarantee your program does what it should do. From now on it may crash at any other place.
Instead of preventing the crash I suggest you FIND the outlaw that dares to overwrite the forbidden memory and corrupt the heap.
Fix your code instead of trying to ignore such a serious error. You shouldn't have such serious memory bugs in your production code. AFAIK there's no simple way to handle this and it's for a good reason.
Btw, I thought the dialog appears only in debug mode. In release mode the memory error should not be detected and the application should crash immediately (or run with a corrupted heap, yuk).
Many Windows programs use HeapSetInformation with HeapEnableTerminationOnCorruption to ensure that the program crashes immediately when heap corruption is detected. This is a security measure, since heap corruption might be exploitable. Crashing immediately on heap corruption is the only sane thing to do.
But if you're trying to debug, and it's a release build, this setting can make it difficult to debug the problem. It sounds like you have a module that run inside somebody else's app (though I'm not sure from your description). In that case, it might be that the other application is setting the heap termination flag. Unfortunately, it cannot be unset once set (per process).
You'll need to attach a debugger to generate a dump file when the crash occurs and try to debug from that.