How can I retrieve the source file of a compiled method? - c#

I'm really stumped by this one!
The StackFrame object (MSDN Link) has a GetFileName method that returns the original path of the source file that compiled the executing method (provided symbols were generated and included with the executing assemblies). It looks like this information is used to generate full exception text.
I'm trying to find a way to get at this information if the method isn't currently executing. I've been poking around the reflection API and haven't seen a way to get at this information. I assume it must be in there somewhere.
Does anyone else know of a reflection based method (or indeed any other method) that can get me the code file name?
Any ideas, comments or abuse gratefully accepted.
Many thanks!

Reflection can only provide type information from the assembly metadata. Getting the address requires the .pdb debugging file and the address of the function in memory, as compiled by the JIT compiler. You can't get the address without the StackFrame.GetNativeOffset() method or the debugger interfaces, assuming the method is even compiled. The latter approach can't work in-process, a program cannot debug itself.
The CLR doesn't have any trouble because it can retrieve the method address from the stack frames when it processes the exception. That's still an imperfect art, it cannot see addresses of methods that were inlined. Having those stack frames is the required first step.

You can read the information from the .pdb file and evaluate it yourself. It contains all the data you need. I haven't finished reading the code but my understanding is this:
You get the metadata token from the method in question through reflection
You query the pdb data for that token
The pdb entry contains the source file name and line number
A metadata token is a 32 bit number that consists of a type byte and a serial number. That token describes every single entity in a .NET assembly file: types, type references, methods, fields, and so on. That number is worth more than the full namespace, type, method name and signature of a method, and it's easier to handle. But be aware that it's generated by the compiler and may be different in every build, so you always need the .pdb file from the same build.
The pdb file contains entries about which IL offset in what method comes from which source location. If you don't have a StackFrame but only a method, you'll probably find multiple entries about the method so you can either use the one with the smallest offset, or describe the entire range in the source code that defines the method.
Here are some links for further reading, the search term is "pdb2xml" which is an old code sample by Microsoft:
http://blogs.msdn.com/b/jmstall/archive/2005/08/25/pdb2xml.aspx
http://blogs.msdn.com/b/jmstall/archive/2005/08/25/sample-pdb2xml.aspx
Since the .NET API for reading .pdb files requires to have the assembly files available, this conversion should be done directly after the build to keep the generated XML file really portable.
I'm actually building this method in my .NET logging solution, FieldLog, to allow source location resolution from crash logs from release builds, and to de-obfuscate stack traces from obfuscated assemblies.

Use RedGate Reflector decompiler to inspect the assembly containing the class.

Related

Get Specific information from thrown exception

Lets consider that we have an Exception ex thrown in the code. Now in the catch body, I want to have access to six pieces of information:
Solution Name
Project Name
NameSpace Name
File Name
Method Name
Line Number
What I already know is that using
System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(e, true);
I can have access to some of these information(full path of file, line number, etc). But still this information is not all I need. For example, I do not know how to extract solution name or namespace name from trace. Apparently parsing the path for the file is also not an option because different errors can have several layers of file and folders hierarchy and one global rule does not work for all of the errors.
I wonder is there any way to have access programmatically to these info?
Many thanks.
In all likelihood you're not going to get something totally ideal for what you're asking for, but I'll share some tools and thoughts you might not have known about or considered:
There are some attributes (CallerFilePathAttribute, CallerLineNumberAttribute, and CallerMemberNameAttribute which, when added to an optional method parameter, will cause the compiler to automatically insert a default value based on the context of the code being compiled. You could create a helper method with attributes like this to capture the information you want.
There are tools like Fody, known as "IL Weavers", which can run after the main compile process and change the compiled code in a particular way. For example, your code could be written to make a simple call to one method, but when it's compiled the weaver could change the code to create a bunch of contextual information and pass it to a logging method.
If you're organizing your code well, you can often ensure that the namespace, class, and method (which are all captured as part of the stack trace) are enough information that you can guess the solution, project, and File Name.
When you're catching an exception, you typically want to either log what happened and handle the exception in a particular way, or simply wrap the exception in another exception with more contextual information. If you choose the latter, then the namespace, class, and method name will get included in the stack trace of the thrown exception. So when it's logged further up the stack you'll have access to that data.

"Interface" for .Net Resource files

I am building a multi-language MVC application and have a series of resource files with translated strings for messages that will be displayed to the user.
Is there any way of ensuring that any resource files added in the future have all required keys and are spelled correctly?
As an analogy, if the resource file was a regular class, you could provide an interface to ensure that all required method and properties were present in the implementing class. Is there a similar concept for resource files?
I've been unable to find a supported way to enforce an explicit contract upon a .resx file. Since your goal is ultimately to catch implementation errors before they show up at runtime (and compile time checking isn't possible), I recommend falling back to static code analysis. Luckily, .NET makes this trivially easy:
Use the System.Resources.ResXResourceReader class to read the contents of the resx files to be validated.
Implement a test that asserts against all required keys in the "contract" you'd like to enforce on the resx.
Test should run as part of an existing test suite, and failure will warn a developer of the implicit contract before encountering the problem at runtime.
Since your resource files will exist in a known location, you can trivially ensure that the tests run against all resx files in that directory. In this way, you don't even need to update the test when new resource files are added, only if the contract changes.
I've used a similar approach to help with maintenance of stored procedure names kept in (an extensive number of) resx files. Since the resource files are spread across dozens of projects, manual maintenance is tedious and error-prone -- in other words, it doesn't get done. The static code analysis approach has yielded few downsides, and I think it would work well in your case as well.
Landing page for resource files on MSDN
ResXResourceReader on MSDN
System.Resources.ResXResourceReader requires a reference to System.Windows.Forms. It's available on both .NET and Mono.

How to print the current code, which executes a program in runtime?

I have an application ( web-service ).
I want to print some function's hints/description of it, but NOT from the DB, textfile or other prepared context, BUT from the current web-service, which is running in live mode.
I want just to copy the source code of it and then post it via web to the client for showing the real function definiton in realtime/runtime. It's important to make him always available to look the fresh changes and for NOT depending on perviously required prepared context for hints.
Are there any suggestions?
I know, that CLR metadata is easy to disassemble and may there is a way to do it for my aim, what do you think?
You can not access the code of the function in execution, but I doubt that you actually need a code of the function itself, instead you need a definition of the function.
For this you can use StackTrace class, that provides information about StackTrace at runtime.
This future you can be implemented only by embedding your classes and methods with attributes after the assembly has been built only. The logic is:
Build you assembly
On post-build execute utility which:
gets as parameters you assembly and path to source code
finds methods' and classes' definitions in source code files
using somesthing like PostSharp adds attribute to every method and class of your assembly (attribute will contain method or class code)
at runtime service will find this attribute value and will use it as you need.

How to get Classes and methods from a .cs file using Reflections in C#.?

How to get the classes that are available in a '.cs' file.? Like we can get the classes and methods in an Assembly using,
Assembly.GetTypes() and Type.GetMethods()
to get the Class and methods in an Assembly.
Similarly how to get all the classes present within a C# file(.cs file).? I need to get the classes in a .cs file from which i can easily get the methods within them and further details like parameters of methods etc.
Short of using a C# parser, there's no direct way of doing it. You could compile the .cs file using CSharpCodeProvider (which only works if the file compiles on its own and you can tell all the referenced assemblies to the compiler) and use reflection on the resulting assembly.
I recommend you to use a parser generator tool to generate a quick c# parser, you can use Antlr.
Also you can check this and this
The compiler erases all notions of a codefile from your code as it is compiled. That being said perhaps it is possible to retrieve the information you want from debugging symbols if they are available in your assembly.
From with in the class you can always call
this.GetType()
or outside the class you can always call
obj.GetType()
however when you compile an application, which is required for reflection to work, you can no longer get their definitions by file.
I've done this previously by invoking the C# compiler, compiling the C# file and then using reflection on the outputted type. This is possible if the C# file is a standalone file and doesn't have any dependencies.
However, the correct way would be to use a parser - something which isn't that easy to do. There are a couple of options available, MinosseCC being one of them.
Incidentally, C# 5.0 will make it a lot easier to compile code on the fly by being able to compile a String and getting back executable code. Can't wait for this - it's sure to confuse everyone that reads my code.
First of all, there is no such thing as the .cs file in which a class is defined. A class can be marked as partial and parts can be defined in several .cs files.
When you compile with debug information, the filenames for each method remain in the assembly (for each line of the source file, the corresponding IL commands are tagged).
Unfortunately, I don't know an easy way to get to that information from within the running application (without parsing the assembly file manually).
If you are safe calling the method, you can call it and in parallel construct a stack trace (from another thread) - in the StackFrame object you will find the original file name. But this is slow (as you have to call every method just to find that the filename is different) and risky (what if the method formats your hard drive?).
So, the only way you could go is try to parse the .cs file with a parser like AntLR yourself.

Can I get the line of code that caused an exception?

Other than reading the GetFileName() file and reading to line GetFileLineNumber() of a stackframe from
new StackTrace(exception).GetFrame(x)
is there a way to get the actual line of code (as a string) which caused an exception?
Thanks
I don't think so. The code is compiled, therefore it is no longer available.
However, if you also have the source code available, there may be a few workarounds.
No, that's your only option as far as I know. In order to get the original line of code that caused the exception, then it's necessary to have the source available. That the StackFrame already enables you to get the line number (via the debug symbols - the PDB file in most cases), makes it straightforward enough, I'd say.
Is there any particular problem with the method you suggested?
There is no reliable way to do this because line information is not stored in DLL files. The information which maps blocks of IL into source code lines is stored within the PDB file. You'd need to access the PDB in order to get the line information for an exception.
There is sufficient information on the StackFrame class to get the appropriate ISymUnmanagedMethod class if the PDB is available. Mainly you just need the method token and the current offset into the method. This does require you to understand the internal structure of the PDB and I'm not sure if it's documented anywhere.
PDB API: http://msdn.microsoft.com/en-us/library/ms233503.aspx
It would be compiled, so at run time you would only have the IL. At best, you could get the IL and decompile it back to C#, much like reflector does.
Post moretem debugging is difficult, but not impossible. There are tools you can use (here and here for example) as well as techniques.
You can get line using a try catch block:
catch(Exception exception) {
//exception.StackTrace at the first line has the line you are looking for
}

Categories

Resources