Is there an option/attribute/... that prevents VS's debugger from stopping a debugging session inside a specific method? I'm asking because I'm suffering from the BSoD that the class Ping of .NET 4.0 sometimes triggers. See Blue screen when using Ping for more details.
private async Task<PingReply> PerformPing()
{
// Do not stop debugging inside the using expression
using (var ping = new Ping()) {
return await ping.SendTaskAsync(IPAddress, PingTimeout);
}
}
DebuggerStepthrough
Fun fact you can set it at a method level or a class level.
Instructs the debugger to step through the code instead of stepping into the code. This class cannot be inherited.
Tested with
using System;
using System.Diagnostics;
public class Program
{
[DebuggerStepThrough()]
public static void Main()
{
try
{
throw new ApplicationException("test");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
And the debugger didnt stop in the MAIN method
This answer ignores your BSoD and your Ping class, and focuses on the very interesting question of:
How to prevent the Visual Studio Debugger from stopping inside a specific method
(Note: this is "stopping", with an "o", not "stepping".)
So:
What seems to work nowadays is the [DebuggerHidden] attribute.
So, for example, consider the following method:
///An assertion method that does the only thing that an assertion method is supposed to
///do, which is to throw an "Assertion Failed" exception.
///(Necessary because System.Diagnostics.Debug.Assert does a whole bunch of useless,
///annoying, counter-productive stuff instead of just throwing an exception.)
[DebuggerHidden] //this makes the debugger stop in the calling method instead of here.
[Conditional("DEBUG")]
public static void Assert(bool expression)
{
if (expression)
return;
throw new AssertionFailureException();
}
If you then have the following:
Assert(false);
The debugger will stop on the Assert() invocation, not on the throw statement.
Related
In my Azure Functions 2.x Project, i have a part of an Function, a try-catch block without finally, that more or less look like this.
Dictionary<string, int> varDict = null;
Tuple<string, DateTime> varTupl = null;
try
{
varDict = await Core.GetDict(lcLat.Value, lcLong.Value);
varTupl = await Core.GetTupl(lcLat.Value, lcLong.Value);
}
catch (AggregateException ae)
{
ae.Flatten().Handle(ex =>
{
// `log` is an ILogger, the standard Azure Functions passed param
log.LogError(ex, ""); // Writes the ex's error
Debug.WriteLine(""); // Writes the ex's error
// the written content is ommited for readability sake
// But will be shown below
return true;
});
}
catch (Exception ex)
{
// Does exactly like Handle() Does
}
if(varDict != null && varTupl != null)
{
// The Code won't go here, and always return HTTP 500 Instead
}
else
{
// Here neither
}
The Run method itself is an async Task<IActionResult>, with Core as a static public class containing GetDict() and GetTupl() methods, each of them are also an static async Task<T> with their respective T return type and both doesn't have any try-catch block, only using (which are not supposed to throw any exceptions, right ?)
The problem is, even though (i assume) the exceptions raised then bubbled up into my try-catch block, even with my catch block running printing the exception with my formatting from catch block, as shown in the screenshot ,my Azure Functions keep returning HTTP Error 500, skipping the rest of the code after the try-catch block
What i have tried
Disable 'Just My Code' debugging options in my Visual Stuido 2017
Adding AggregateExceptions, before this it's only catching for Exception
Flatten the AggregateException before Handle() it
Is this common on local development environment, or it's just me handling everything incorectly ?
Also, the output window keep printing out something like this
and this
even in idle state (while the HTTP endpoint isn't being invoked, just run in debug mode, idly waiting for invocation)
are these something that i have to concerned about ? are those even related with my problem
After updating Windows 10 to creators update with .net 4.7 I have a critical issue on starting very simple code.
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
class Program
{
private int? m_bool;
private bool prop {get{ return false;}}
void test()
{
//nothing
}
private object Test()
{
if (prop)
{
try
{
test();
}
catch (Exception) {}
m_bool = 1;
}
return null;
}
static void Main(string[] args)
{
new Program().Test();
}
}
Seems the similar issue is https://github.com/dotnet/coreclr/issues/10826
Anyone knows how to avoid that?
The issue is caused when an optimization is running on an unreachable basic block.
In your case the compiler inlines the get_prop method (which unconditionally returns false). This leads to JIT compiler to consider the region as unreachable. Typically the JIT compiler removes the unreachable code before we run the optimization, but adding a try/catch region causes the JIT not to delete these basic blocks.
If you want to prevent the issue you could disable optimizations, disable the inlining of get_prop or change the implementation of the get_prop method to be:
static bool s_alwaysFalse = false;
private bool prop {get{ return s_alwaysFalse;}}
We have had a couple of reports of this issue and we do have a fix ready and it will be provided to users in a upcoming update.
I'm going to provide a simple example of what I'm trying to do -- hopefully it is possible?
I basically have a class that does a whole ton of formatting/analyzing to the data. As a result, there a lot of things that can go wrong with this. The problem I have is handling the class when things go wrong. I want all execution of this class to stop once an error has occurred.
This class (AnalyzingStuff) is called from a parent form that does various things based on the result of this classes execution.
Ideally, I would fire an event named say "ABORT".
So in this code here I do the following:
Class AnalyzingStuff{
public event EventHandler ABORT;
public AnalyzingStuff(){
for(int i = 0; i < 999999; i ++){
AnalyzeSomeStuff();
AnalyzerSomeOtherStuff();
}
MoreStuff();
OtherStuff();
}
private void AnalyzeSomeStuff(){
if(someconditionNotMet){
//EXIT OUT OF THIS CLASS, STOP EXECUTION!!!
this.ABORT.Invoke(this, null);
}
}
}
Calling this 'ABORT' event, I would stop the execution of this class (stop the loop and not do anything else). I could also catch this event handler in some other parent form. Unfortunately, I can't find any way of stopping the execution of this class.
Ideas so far:
The obvious answer is to simply set a flag and constantly check this flag over and over in multiple places, but I really don't like this approach (my current implementation). Having to check this after every single method call (there are MANY) is ugly codewise.
I thought maybe a background worker or something where you could cancel the execution of the DoWork?
Use a form as a base class for the AnalyzingStuff so I can simply call "this.Close();".
What do you think is the best approach to this situation? Are these the best solutions? Are there any other elegant solutions to what I want here or am I going completely in the wrong direction?
EDIT: I have a series of try/catch blocks used throughout this code that is used to handle different errors that can occur. Unfortunately, not all of them call for an Abort to occur so they need to be caught immediately. Therefore, try/catch not the most ideal approach.. or is it?
Don't do analysys in the constructor. Do it in a main Analyze() method.
Use exceptions. If you want to abort because of a fatal error, throw a fatal exception. That is, throw an exception that you don't catch within the scope of the main analysis method.
class Analyzer
{
public Analyzer()
{
// initialize things
}
public void Analyze()
{
// never catch a fatal exception here
try
{
AnalyzeStuff();
... optionally call more methods here ...
}
catch (NonFatalException e)
{
// handle non fatal exception
}
... optionally call more methods (wrapped in try..catch) here ...
}
private void AnalyzeStuff()
{
// do stuff
if (something nonfatal happens)
throw new NonFatalException();
if (something fatal happens)
throw new FatalException();
}
}
outside:
{
var analyzer = new Analyzer();
try
{
analyzer.Analyze();
}
catch (FatalException)
{
Console.WriteLine("Analysis failed");
}
}
If you don't like using exception this way, you can accomplish the same thing by having every analysis method return a bool:
if (!AnalyzeStuff())
return false;
if (!AnalyzeMoreStuff())
return false;
...
return true;
But you end up with a lot of return statements or a lot of braces. It's a matter of style and preference.
Could you throw an Exception if things go wrong, and run a try catch around where you call the method in the loop?
if you do this you could do stuff if the class fails (which you will put in the catch), and stuff you could do to close connections to database ++ when it is done.
or you could make the methods return an int, to tell if the execution of the method was valid. ex. return 0; is valid execution, return 1-500 would then might be different error codes. Or you might go for the simple version of passing a bool. If you need to return values from methods other than the error code you could pass these as OUT variables. example following:
Class AnalyzingStuff{
public AnalyzingStuff(){
for(int i = 0; i < 999999; i ++){
if (!AnalyzeSomeStuff() || !AnalyzerSomeOtherStuff())
break;
}
MoreStuff();
OtherStuff();
}
private bool AnalyzeSomeStuff(){
if(someconditionNotMet){
return false;
}
return true;
}
}
You can of course use your event. I just removed it for the simplicity of it.
Update: I've filed a bug report on Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/568271/debugger-halting-on-exception-thrown-inside-methodinfo-invoke#details
If you can reproduce this problem on your machine, please upvote the bug so it can be fixed!
Ok I've done some testing and I've reduced the problem to something very simple:
i. Create a method in a new class that throws an exception:
public class Class1 {
public void CallMe() {
string blah = null;
blah.ToLower();
}
}
ii. Create a MethodInfo that points to this method somewhere else:
Type class1 = typeof( Class1 );
Class1 obj = new Class1();
MethodInfo method = class1.GetMethod( "CallMe" );
iii. Wrap a call to Invoke() in a try/catch block:
try {
method.Invoke( obj, null ); // exception is not being caught!
} catch {
}
iv. Run the program without the debugger (works fine).
v. Now run the program with the debugger. The debugger will halt the program when the exception occurs, even though it's wrapped in a catch handler that tries to ignore it. (Even if you put a breakpoint in the catch block it will halt before it reaches it!)
In fact, the exception is happening when you run it without the debugger too. In a simple test project it's getting ignored at some other level, but if your app has any kind of global exception handling, it will get triggered there as well. [see comments]
This is causing me a real headache because it keeps triggering my app's crash-handler, not to mention the pain it is to attempt to debug.
I can reproduce this on my .NET 4 box, and you're right -- it only happens on .NET 4.0.
This smells very much like a bug to me, and should go on MS Connect. Major bummer if this is tripping your crash handler. Sounds like a non-pleasing way to work around this is to wrap the invoked method inside its own handler. :-(
One thing I can not reproduce, though, is tripping the crash handler. Here's my program:
namespace trash {
public class Class1 {
public void CallMe() {
string blah = null;
blah.ToLower();
}
}
class Program {
static void Main(string[] args) {
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
var class1 = typeof(Class1);
var method = class1.GetMethod("CallMe");
try {
var obj = new Class1();
method.Invoke(obj, null); // exception is not being caught!
}
catch (System.Reflection.TargetInvocationException) {
Console.Write("what you would expect");
}
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
Console.Write("it would be horrible if this got tripped but it doesn't!");
}
}
}
You can't catch all exceptions. There's a few assumptions in your example. You are, for instance, assuming the exception was raised on the calling thread. Catching unhandled exceptions on other threads depends on which runtimes you're using (console, winforms, WPF, ASP.Net, etc).
Additionally, calls to System.Environment.FailFast() do not generate any handlable condition - the process is effectively terminated with no chance for intervention.
I have a command line program in C# that I've wrapped with a try-catch block to keep it from crashing the console. However, while I am debugging it, if an exception is thrown somewhere in the DoStuff() method, Visual Studio will break on the "catch" statement. I want Visual Studio to break where the exception occurred. What's the best way to do this?
Comment out the try?
A setting in Visual Sudio?
An #if DEBUG statement?
static void Main(string[] args)
{
try
{
DoStuff();
}
catch (Exception e)
{ //right now I have a breakpoint here
Console.WriteLine(e.Message);
}
}
private void DoStuff()
{
//I'd like VS to break here if an exception is thrown here.
}
You can turn on First chance exceptions in VS. This will allow you to be notified as soon as an exception is raised.
I think setting VS to break on uncaught exceptions and wrapping the try/catch in ifdefs is how I would go about doing it.
There is an option to "Break on all exceptions". I'm not sure what version of VS you are using but in VS 2008 you can press Ctrl + D, E. You can then click the checkbox the Thrown checkbox for the types of exceptions you want to break on
I believe in previous versions of VS there was a Debug menu item to the effect of "Break on all exceptions". Unfortunately I don't have a previous version handy.
Here's how I do it for console tools running at continuous integration server:
private static void Main(string[] args)
{
var parameters = CommandLineUtil.ParseCommandString(args);
#if DEBUG
RunInDebugMode(parameters);
#else
RunInReleaseMode(parameters);
#endif
}
static void RunInDebugMode(IDictionary<string,string> args)
{
var counter = new ExceptionCounters();
SetupDebugParameters(args);
RunContainer(args, counter, ConsoleLog.Instance);
}
static void RunInReleaseMode(IDictionary<string,string> args)
{
var counter = new ExceptionCounters();
try
{
RunContainer(args, counter, NullLog.Instance);
}
catch (Exception ex)
{
var exception = new InvalidOperationException("Unhandled exception", ex);
counter.Add(exception);
Environment.ExitCode = 1;
}
finally
{
SaveExceptionLog(parameters, counter);
}
}
Basically, in release mode we trap all unhandled exceptions, add them to the global exception counter, save to some file and then exit with error code.
In debug more exception goes right to the throwing spot, plus we use console logger by default to see what's happening.
PS: ExceptionCounters, ConsoleLog etc come from the Lokad Shared Libraries