Throwing exception on line called from library - c#

I am building a library which contains a lot of wrappers for various bits of code I use a lot.
My library code:
public static void Create(string name, string location, List<string> commands)
{
if (!Directory.Exists(location))
{
throw new DirectoryNotFoundException();
}
else
{
File.WriteAllLines(Path.Combine(location, name), commands);
}
}
My sample app using the library
AwesomeFunction.Create("Foo", "C:\\DoesntExist\\Bar", new List<string> { "List of stuff" });
If the directory given isn't found it throws on the line throw new DirectoryNotFoundException(); which makes sense, but I need it to throw on the AwesomeFunction.Create function.
This will stop it switching to the library code if it throws, instead it will highlight the AwesomeFunction line in VS.
A comparable example would be throwing an exception on
Directory.Delete("C:\\DoesntExist\\Bar");
Where it will highlight that line, even though the throw is in the Directory class.
Any help appreciated.
EDIT
If I copy the library to a different location i.e. C:\mylibrary it still opens the source code for it, even though I didn't reference it through a project.
Another problem I found it that when I don't add it from my projects I don't see my XML comments on the functions.
Any ideas?

You could achieve that by using an assembly reference instead of a project reference for the library. This way you will not have the source code of the library in the consuming project and VS will break on the AwesomeFunction.Create function call. That's what happens when an exception is thrown inside the Directory.Delete call that you provided. Since you don't have the source code of this method linked in, VS simply stops on this line and not on the actual line inside this method that threw the exception. Obviously in the exception stacktrace you get the full stack of method calls and the origin of the exception.

Related

Unable to load true type font in SharpDX

I've been trying to draw custom fonts in SharpDX. I basically followed the example from GitHub.
Whenever I try to draw the font using the D2D1 RenderTarget it throws the error below:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: "Cannot add a reference to a nonreferenced item"
So after a long time of debugging I couldn't find where was the issue so I decided to try to compile the project from the example above and I got the exact same error (it outputs to debug console that there is a 'System.ObjectDisposedException' Exception in SharpDX.dll)
Edit: The exit code for the program is 3; it may be useful.
I concluded that the issue was from the library itself. In my opinion there is a low chance that it's the case but if the example itself there is surely something wrong here. I'm not too familiar with DirectX in general either so I won't refuse an advise or two.
Note that in what I saw, the font was correctly loaded in the TextFormat and TextLayout.
I tried to modify my code, remove Dispose() method, replaced my whole code with the one of the example and tried to find the root of the problem, without success. I'm expecting the DrawText method from the RenderTarget shouldn't throw such error and draw the text with the font I imported.
UPDATE: The example shown is for SharpDX 3.0.0, this explains why it does not work properly. But I still need to know how can I fix the issue for SharpDX 4.2.0
How can I fix this issue if possible?
The error basically means there's a COM object that has a refCount value that is down to 0, so it shouldn't be used anymore. The code is located in SharpDX's CallbackBase.cs:
public int AddReference()
{
var old = refCount;
while (true)
{
if (old == 0)
{
throw new ObjectDisposedException("Cannot add a reference to a nonreferenced item");
}
var current = Interlocked.CompareExchange(ref refCount, old + 1, old);
if (current == old)
{
return old + 1;
}
old = current;
}
}
So it's "just" a COM reference issue. The error is thrown by the CustomFont.ResourceFontFileStream.cs file that derives from CallbackBase (it's implements a COM object), so there's a reference issue on the ResourceFontFileStream type.
How SharpDX handles references in the general case is a bit obscure to me (it has lots of wrapper and boilerplate code) but you can fix it if you add a reference when a ResourceFontFileStream is given out by a COM method. This is how things are done normally in COM methods: when an out object is given back to the caller, the callee calls AddRef () on the object.
So, you can change the ResourceFontLoader.cs file, like this:
// this implements IDWriteFontFileLoader::CreateStreamFromKey https://learn.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritefontfileloader-createstreamfromkey
FontFileStream FontFileLoader.CreateStreamFromKey(DataPointer fontFileReferenceKey)
{
var index = Utilities.Read<int>(fontFileReferenceKey.Pointer);
_fontStreams[index].AddReference(); // add this line
return _fontStreams[index];
}

Visual Studio not stepping into same-project constructor

I am trying to debug some code, as a class is throwing an exception when called.
The code is:
public TrackingStrategy1(string Name, RobotGeometry geometry)
{
trackSystem = new TrackSystem(geometry, Name);
}
which calls (In the same project):
public TrackSystem(RobotGeometry geometry, string Name)
{
finder = new FindModel(geometry); //breakpoint inserted here fails
finder.InitModel();
finder.useGPU = false;
}
I am getting the exception 'Method Not Found: TrackSystem.FindModel..ctor(RobotGeometry). However, a break point inserted at this point is not hit. If I comment out the new line, I get the same exception for the next line.
FindModel is referenced in another project contained in the solution, which I have re-referenced to several times, followed by a rebuild.
Why does Visual Studio not stop at breakpoints inserted in this constructor?
Before loading each class, Visual Studio was checking for the existence of all external dll method calls.
Because this occurs before the constructor is called, the break points in the constructor are never called.
In this case, the reason for failure was that 2 different projects were referencing different versions of FindModel - and the wrong one for this project was used in the build.

exception call stack truncated without any re-throwing

I have an unusual case where I have a very simple Exception getting thrown and caught in the same method. It isn’t re-thrown (the usual kind of problem naïve programmers have). And yet its StackFrame contains only one the current method. Here’s what it looks like:
at (my class).MyMethod() in C:\(my file path and line)
In reality there are probably 30 methods leading up to this in the VS2010 debugger's call stack, going across half a dozen different assemblies. It seems impossible for all that to have been optimized out. Moreover, this code is built in debug mode, without optimizations, for .NET 4. I even have (based on http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx) .ini files (including one named [app].vshost.ini) in the same folder containing:
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
Also, the method calls are not at the end of methods, so tail-recursion optimization seems further unlikely.
As to how it is called: there are no uses of reflection on the call stack, no Invoke() or BeginInvoke() of any kind. This is just a long chain of calls from a button click. The click handler is about 10 calls down the call stack. Beneath that you have the usual WndProc, NativeWindow.Callback, native/managed transitions, and message loop. This is ultimately inside a ShowDialog() call which is run from a C# EXE assembly.
Now, I found that I can construct instances of the StackTrace class in my catch handler, and if I pass the Exception object, the call stack is also short. If instead I just call new StackTrace() with no arguments, it yields a complete call stack.
I’ve used Reflector in an attempt to debug into the internals of the Exception class getting thrown and its call stack constructed, but I couldn’t set breakpoints in Exception or in StackTrace. I could set them in Environment.GetStackTrace() and this method (which Exception calls) does not appear to get called during the construction and throwing process, but I don’t know if the debugger is really working properly. (This method does get triggered for some other things though, so I'm not sure what to make of it.)
Here’s an excerpt of the method:
private void MyMethod()
{
...
try
{
throw new ApplicationException("Test failure");
}
catch (Exception e)
{
StackTrace stackTrace1 = new StackTrace(e);
StackTrace stackTrace2 = new StackTrace(e, false);
StackTrace stackTrace3 = new StackTrace(e, true);
StackTrace stackTrace4 = new StackTrace();
string STs = stackTrace1.ToString() + "\n---\n"
+ stackTrace2.ToString() + "\n---\n"
+ stackTrace3.ToString() + "\n---\n"
+ stackTrace4.ToString();
Log(EventSeverity.Debug, STs);
...
}
}
It’s really pretty simple: Throw exception, catch and log it.
I get the same results either in the debugger or when running standalone—a one-line call stack. And I know I have seen this problem elsewhere in our code base. Previously I had assumed it was due to re-throwing exceptions, but in a lot of cases it we log right inside the initial catch block. I’m quite baffled and all the web searching I’ve done hasn’t produce anything.
This is a little too much to add as a comment to the answer provided, but here's some more information:
I now see that this behavior is discussed at
http://dotnetthoughts.wordpress.com/2007/10/27/where-did-my-exception-occur/ and that it is actually described at http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx (though I think one could easily miss what they're saying there).
So I guess my "solution" will be a little hit-or-miss. We have a central method we usually call to format exceptions. Inside that method, I'll create a new StackTrace() both with and without the Exception object. Then I'll look for the method that is at the bottom of the Exception's stack trace, and display everything beneath that in the new StackTrace(), indicating it was called by that series of calls.
The down side of course is that if this method isn't used, the information won't be there. But I had to expect some kind of code change somewhere.
When an exception is thrown, only a partial stack trace will be used in the Exception.StackTrace property. The stack only shows calls up until the method that is catching the exception. To get the full stack (as you have noted) you should create a new StackTrace() object.
I can't find any links on it at the moment but I believe the stack trace is built by walking up the stack while throwing the exception. Once the exception reaches a catch block, the stack stops being compiled. Therefore, you only get a partial stack.
Typically, a catch block is not concerned with who called it, but where the exception is originating from.

AccessViolationException in debugger with only managed code and WCF service

This application has a WCF web service that is called by a WinForms app. The WinForms app has a class WCFCache to manage data from the service. There is a section like this in that class to manage an optional custom configuration section that a subset of the machines have:
private bool? m_HasCustomConfiguration = null;
public bool HasCustomConfiguration
{
get
{
if (m_HasCustomConfiguration == null)
m_HasCustomConfiguration = (CustomConfiguration != null);
return (bool)m_HasCustomConfiguration;
}
}
private WCFService.CustomConfiguration m_CustomConfiguration = null;
public WCFService.CustomConfiguration CustomConfiguration
{
get
{
if (m_CustomConfiguration == null)
{
if (m_HasCustomConfiguration.HasValue
&& !m_HasCustomConfiguration.Value)
return null;
try
{
using (WCFService.WCFServiceClient wcf = new WCFService.WCFServiceClient())
{
m_CustomConfiguration =
wcf.GetCustomConfiguration(Machine.ProcessID);
// Above method returns null if no record exists.
m_HasCustomConfiguration = (m_CustomConfiguration != null);
}
} catch (Exception e) {
// Error logging & re-throw
}
}
return m_CustomConfiguration;
}
}
When I step through the debugger in code that calls either of the above properties like this:
if (!Program.WCFCache.HasCustomConfiguration)
return new List<CustomComponents>();
...it throws the following exception:
System.AccessViolationException was unhandled
Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Source="System.Windows.Forms"
...
When I step onto the line containing the reference, there is a long pause, followed by a VS popup with the exception.
The exception doesn't appear when I just put a breakpoint after the above code has executed. It doesn't even appear when I put a breakpoint inside the accessors of the properties. It only occurs when I step onto a line with one of those properties from the outside. (So there is a workaround, but it can be a pain.)
Why is this happening? Can I stop it?
Edit: The whole application was written in the last year in 3.5 C#/.NET with WCF communicating between components; meaning, we don't have legacy unmanaged DLLs. Just two unmanaged calls: one to advapi32.dll when the WinForms app is loading, in the username detection procedure. The issue I'm having happens only in this one place in the code, in a place that is about as unrelated to the login section as you can get. The other is to kernel32.dll, in a GC force-flush long after anything is done with the results from calls like the one above.
Are you using any P/Invoke or other such native code? Odds are, that's where you should start looking.
This exception is a symptom of a larger problem, namely memory corruption (that what the exception says, after all). If this was a native application, you'd get a crash.
So, look at any native calls, make sure they're operating correctly, maybe run them under a debugger to try and trap the error closer to home.
Sorry, can't really give better advice given the circumstances.
I eventually found that others have encountered this situation and that it is likely a Visual Studio bug. I was using VS 2008 when the problem occurred.

GetGlobalResourceObject exception handling

I have a project that makes extensive use of the GetGlobalResourceObject which is a member of the System.Web.UI class. It works fine providing english or french labels to the bilingual C#/ASP.NET application.
But....if the reference in the resource file is missing or malformed the application crashes
There are hundreds of calls like this
GetGlobalResourceObject("XXX.WebResource", "Remove")
Is there any way to encapsulate the GetGlobalResourceObject with an exception handler so that it returns null and logs it if there's a problem without adding a try/catch to each call?
I am new to C# so I don't know if I can override the GetGlobalResourceObject with my own class and then do a search and replace. Surely there is a better way.
Kevinsky
You can write your own version of GetGlobalResourceObject to embed the exception handling and logging in that:
public static Object MyGetGlobalResourceObject (string classKey,
string resourceKey)
{
try
{
return GetGlobalResourceObject (classKey, resourceKey);
}
catch (MissingManifestResourceException ex)
{
// log error
return null;
}
}
This code is provided as an starting point
You could even write it as an extension method on HttpContext.
You will have to do a global search and replace to call this rather than the base method, which isn't the most elegant solution, but it will work.

Categories

Resources