Long story short: some third party unmanaged dll, which I use in my project, apparently dumps its errors into Visual Studio Output window (shows output from "Debug") during runtime. It looks like this:
*** WARNING ERROR 11 from R3ORP. The degree 0 polynomial fit is a perfect
*** fit within machine precision.
Here is a traceback of subprogram calls in reverse order:
Routine name Error type Error code
------------ ---------- ----------
R3ORP 6 11 (Called internally)
R4ORP 0 0 (Called internally)
R2ORP 0 0 (Called internally)
R2URV 0 0 (Called internally)
RCURV 0 0
USER 0 0
I want to either log these errors or display them in my application.
Is it possible to somehow access the VS output stream from my application? Can I still do it without VS attached to process? I don't need the entire stream, but I want to catch those "warnings" somehow. I've tried adding listeners to Diagnostics.Debug and Diagnostics.Trace, didn't work.
There is! You can implement your own TraceListener-Class.
First write the TraceListener-Class:
class CustomTraceListener : TraceListener
{
public string AllMessages { get; set; }
public override void Write(string message)
{
AllMessages += message;
}
public override void WriteLine(string o)
{
Write(o + '\n');
}
public override string ToString()
{
return AllMessages;
}
}
You can of cause implement custom behavior (like writing to a Textbox etc) in the Write() method.
Then you just have to add an instance of your class to the system's debug trace listeners and you're good:
CustomTraceListener myTraceListener = new CustomTraceListener();
Debug.Listeners.Add(myTraceListener);
Debug.WriteLine("this is a test");
Debug.WriteLine("this is another test");
string result = myTraceListener.ToString();
If this is an unmanaged dll, and the output appears in the Visual Studio output window, that means it is using the OutputDebugString function to write the data.
Because this data is meant for debugging only, there is no guarantee that subsequent versions will still output this info, or stick to the same format.
If that is of no concern to you, a quick google search on 'c# capture debug output' yields this answer.
That's a really fascinating question here.
I found a Solution with the System.Diagnostics.TraceListener class.
sealed class StackOverflowSampleListener : TraceListener
{
// Singleton
public static readonly StackOverflowSampleListener Instance =
new StackOverflowSampleListener();
public void InitializeTracing(bool ReadDebugOutput)
{
if (ReadDebugOutput == true)
Debug.Listeners.Add(this);
else
Trace.Listeners.Add(this);
}
public StringBuilder Buffer = new StringBuilder();
public override void Write(string message)
{
// Do something with your messages!
Buffer.Append(message);
}
public override void WriteLine(string message)
{
// Do something with your messages!
Buffer.Append(message);
}
}
Example in some Form.cs Code:
public Form1()
{
InitializeComponent();
StackOverflowSampleListener.Instance.InitializeTracing(true);
StackOverflowSampleListener.Instance.Buffer.ToString();
}
GuyMontag is absolutly right with his answer, but i prefer a lighter version with an singleton implementation and the possibility collection messages also in the release mode (look at initialize methode).
Related
The Background
I'm writing an application that programatically executes PowerShell scripts. This application has a custom PSHost implementation to allow scripts to output logging statements. Currently, the behavior I'm seeing is that some requests are properly forwarded to my custom PSHost and others are flat out ignored.
Things get even stranger when I started inspecting the $Host variable in my scripts, which seem to suggest that my custom PSHost isn't even being used.
The Code
I have some code that's executing PowerShell within a .NET application:
var state = InitialSessionState.CreateDefault();
state.AuthorizationManager = new AuthorizationManager("dummy"); // Disable execution policy
var host = new CustomPsHost(new CustomPsHostUI());
using (var runspace = RunspaceFactory.CreateRunspace(host, state))
{
runspace.Open();
using (var powershell = PowerShell.Create())
{
powershell.Runspace = runspace;
var command = new Command(filepath);
powershell.Invoke(command);
}
}
The implementation for CustomPsHost is very minimal, only containing what's needed to forward the PSHostUserInterface:
public class CustomPsHost : PSHost
{
private readonly PSHostUserInterface _hostUserInterface;
public CustomPsHost(PSHostUserInterface hostUserInterface)
{
_hostUserInterface = hostUserInterface;
}
public override PSHostUserInterface UI
{
get { return _hostUserInterface; }
}
// Methods omitted for brevity
}
The CustomPsHostUI is used as a wrapper for logging:
public class CustomPsHostUI : PSHostUserInterface
{
public override void Write(string value) { Debug.WriteLine(value); }
public override void Write(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value){ Debug.WriteLine(value); }
public override void WriteLine(string value) { Debug.WriteLine(value); }
public override void WriteErrorLine(string value) { Debug.WriteLinevalue); }
public override void WriteDebugLine(string message) { Debug.WriteLine(message); }
public override void WriteProgress(long sourceId, ProgressRecord record) {}
public override void WriteVerboseLine(string message) { Debug.WriteLine(message); }
// Other methods omitted for brevity
}
In my PowerShell script, I am trying to write information to the host:
Write-Warning "This gets outputted to my CustomPSHostUI"
Write-Host "This does not get outputted to the CustomPSHostUI"
Write-Warning $Host.GetType().FullName # Says System.Management.Automation.Internal.Host.InternalHost
Write-Warning $Host.UI.GetType().FullName # Says System.Management.Automation.Internal.Host.InternalHostUserInterface
Why am I getting the strange behavior with my CustomPSHostUI?
You need to provide an implementation for PSHostRawUserInterface.
Write-Host ends up calling your version of Write(ConsoleColor, ConsoleColor, string). PowerShell relies on the raw ui implementation for the foreground and background colors.
I have verified this with sample code. Instead of calling out to a ps1 file, I invoked Write-Host directly:
powershell.AddCommand("Write-Host").AddParameter("Testing...")
By running a script, PowerShell was handling the exceptions for you. By invoking the command directly, you can more easily see the exceptions. If you had inspected $error in your original example, you would have seen a helpful error.
Note that the value of $host is never the actual implementation. PowerShell hides the actual implementation by wrapping it. I forget the exact details of why it's wrapped.
For anyone else still struggling after implementing PSHostUserInterface and PSHostRawUserInterface and finding that WriteErrorLine() is being completely ignored when you call Write-Error, even though Warning, Debug, and Verbose make it to the PSHostUserInterface, here's how to get your errors:
Pay close attention to https://msdn.microsoft.com/en-us/library/ee706570%28v=vs.85%29.aspx and add these two lines right before your .Invoke() call, like so:
powershell.AddCommand("out-default");
powershell.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
powershell.Invoke() // you had this already
This will merge the Errors stream into your console output, otherwise it apparently doesn't go there. I don't have a detailed understanding of why (so perhaps I shouldn't be implementing a custom PSHost to begin with) but there is some further explanation to be had out there:
http://mshforfun.blogspot.com/2006/07/why-there-is-out-default-cmdlet.html
https://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.command.mergemyresults%28v=vs.85%29.aspx
Also, assuming your host is not a console app, and you're not implementing your own cmd-style character-mode display, you'll need to give it a fake buffer size, because it needs to consult this before giving you the Write-Error output. (Don't give it 0,0, otherwise you get a never-ending torrent of blank lines as it struggles to fit the output into a nothing-sized buffer.) I'm using:
class Whatever : PSHostRawUserInterface
{
public override Size BufferSize
{
get { return new Size(300, 5000); }
set { }
}
...
}
If you ARE a console app, just use Console.BufferWidth and Console.BufferHeight.
Update: If you'd rather get your errors in ErrorRecord objects rather than lines of pre-formatted error text going to your WriteErrorLine override, hook the PowerShell.Streams.Error.DataAdding event and get the ItemAdded property on the event args. Way less unruly to work with if you're doing something other than simple line-by-line output in your GUI.
Take the following C# code
namespace lib.foo {
public class A {
public A (int x) {}
public int GetNumber() { return calculateNumber(); }
private int calculateNumber() { return lib.bar.B.ProduceNumber(); }
public void irrelevantMethod() {}
}
}
namespace lib.bar {
public class B {
public static int ProduceNumber() { return something; }
public void IrrelevantMethod() {}
}
}
I want to produce an assembly that contains the functionality of lib.foo.A.GetNumber(), store it, and later load it dynamically and then execute it.
In order for that to work, I'd need a program that can trace all the required dependencies (listed below), and emit them - including their implementation(!) - in one assembly for storage.
* lib.foo.A(int)
* lib.foo.A.getNumber()
* lib.foo.A.calculateNumer()
* lib.bar.B.ProduceNumber()
Can it be done? How?
In case anyone is wondering, I want to build a system where machine A tells machine B (using WCF) what to do. Since serializing delegates is impossible, my plan is to
1) transport an assembly from machine A to B,
2) load the assembly on machine B,
3) have machine A instruct machine B to invoke the desired method, which is implemented in this new assembly.
Note - this isn't really an answer, more of a nitpicking correction (of sorts)..
When you say "Since serializing delegates is impossible", this isn't strictly true, although I would NOT recommend doing it. This example code effectively "serializes" a delegate:
void Main()
{
Func<int,int> dlgt = FuncHolder.SomeMethod;
var ser = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
byte[] buffer;
using(var ms = new MemoryStream())
{
ser.Serialize(ms, dlgt);
buffer = ms.ToArray();
}
Console.WriteLine("{0} was serialized to {1} bytes", dlgt.GetType().Name, buffer.Length);
using(var ms = new MemoryStream(buffer))
{
dynamic whatzit = ser.Deserialize(ms);
whatzit(1);
}
}
[Serializable]
public struct FuncHolder
{
public static int SomeMethod(int i)
{
Console.WriteLine("I was called with {0}, returning {1}", i, i+1);
return i+1;
}
}
Output:
Func`2 was serialized to 978 bytes
I was called with 1, returning 2
I must emphasize, however, that you probably shouldn't do this. :)
As for the original question:
I'd be very careful about transporting and executing arbitrary code, especially in a production environment; the potential for security breaches is considerable, mainly via injection routes. If you were to take, for example, one of the above suggestions and just blast over the source to execute dynamically, there's little stopping someone from injecting who-knows-what into your "Give me code to run" service.
You'd really need to spell out your exact needs here to really come up with a "good" solution, as there are multiple ways to accomplish the same basic idea:
as mentioned, pass actual source code to the service to load/compile/execute, potentially in a "sandbox" for some aspect of security/protection
distribute all executable code paths in a shared plugin/assembly which is pushed by some trusted process to all remote servers, and reduce your executor code to a single "DoWork" method invocation (i.e., wrap all the details inside the plugin)
Cobble together a rough DSL or other type of pseudo-language, restricted in what it can/can't do, and pass that source around.
rely on .NET remoting: actually go remotely call the methods in the assembly on a remote object via proxy.
For my current 'testing the waters' project, I'm trying to not use any Try-Catch blocks but instead catch each error (other than fatal) in other ways.
Now, when I say catch errors, my very contrived program makes one error which is easy to avoid; It tries to divide by 0 and this can be prevented by an If statement. To keep it simple I have only 1 C# file, with 1 class and two methods. I guess this is like a template, where the Constructor starts a process:
public class myObject
{
public myObject()
{
Object objOne = methodOne();
methodThree(objOne);
}
public object methodOne()
{
//logic to create a return object
int x = 0;
//I've added a condition to ensure the maths is possible to avoid raising an exception when, for this example, it fails
if (x > 0)
int y = 5 / x;
return object;
}
public void procesObjects(Object objOne)
{
//logic
}
}
So, as you can see in methodOne() I've added the if statement to ensure it checks that the maths isn't dividing by 0. However, since I've caught it, my application continues which is not desired. I need a way to cease the application and log the failing for debugging.
So, this is what I think could work:
Create a class called Tracking which for this example, is very simple (or would a struct be better?).
public class Tracking
{
StringBuilder logMessage = new StringBuilder();
bool readonly hasFailed;
}
I can then update my code to:
public class myObject
{
Tracking tracking = new Tracking();
public myObject()
{
Object objOne = methodOne();
if (!tracking.hasFailed)
methodThree(objOne);
if (tracking.hasFailed)
ExteranlCallToLog(tracking);
}
public object methodOne()
{
//logic
int x = 0;
//I've added a condition to ensure the maths is possible to avoid raising an exception when, for this example, it fails
if (x > 0)
int y = 5 / x;
else
{
tracking.hasFailed = true;
tracking.logMessage.AppendLine("Cannot divide by 0");
}
//may also need to check that the object is OK to return
return object;
}
public void procesObjects(Object objOne)
{
//logic
}
}
So, I hope you can see what I'm trying to achieve but I have 3 questions.
Should my tracking object (as it is in this example) be a class or a struct?
I'm concerned my code is going to become very noisy. I'm wondering if when the system fails, it raises an event within the Tracking object which logs and then somehow closes the program would be better?
Any other ideas are very welcome.
Again, I appreciate it may be simpler and easier to use Try-Catch blocks but I'm purposely trying to avoid them for my own education.
EDIT
The reason for the above was due to reading this blog: Vexing exceptions - Fabulous Adventures In Coding - Site Home - MSDN Blogs
Seriously, Dave - try catch blocks are there for a reason. Use them.
Reading between the lines, it looks like you want to track custom information when something goes wrong. Have you considered extending System.Exception to create your own bespoke implementation suited to your needs?
Something along the lines of:-
public class TrackingException : System.Exception
{
// put custom properties here.
}
That way, when you detect that something has gone wrong, you can still use try/catch handling, but throw an exception that contains pertinent information for your needs.
I have written a HttpModule that I am using to intercept calls the the WebResource.axd handler so I can perform some post processing on the javascript.
The module wraps the Response.Filter stream to perform its processing and writes it's changes to the underlying stream.
The problem I have is that the script does not get returned to the browser.
So as a really simple example that just acts as a pass through, the module looks like this:
public class ResourceModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PostRequestHandlerExecute += new EventHandler(context_PostRequestHandlerExecute);
}
void context_PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication context = sender as HttpApplication;
if (context.Request.Url.ToString().Contains("WebResource.axd"))
{
context.Response.Filter = new ResourceFilter(context.Response.Filter);
}
}
}
and the ResourceFilter that just outputs what it receives looks like this:
public class ResourceFilter : MemoryStream
{
private Stream inner;
public ResourceFilter(Stream inner)
{
this.inner = inner;
}
public override void Write(byte[] buffer, int offset, int count)
{
inner.Write(buffer, offset, count);
}
}
I can attach and see the module and filter being invoked, but when I browse to WebResource.axd url I get nothing back.
I have used this pattern to implement modules that perform processing on aspx pages and they work just fine. It appears there is something about the interaction with the WebResource.axd that prevents this working.
I made a small project and recreated your problem exactly. I was running fiddler to have a good look at the response, including headers and found it was only on filters on *.axd files where this happened.
After some searching I found this article by Daniel Richardson who had the same issue.
Turns out that the System.Web.Handlers.AssemblyResourceLoader (which axds go through) sets a flag to ignore further writes.
Daniel gives an example of using reflection to unset this flag and allow your filter to work on the result of the axd. I tried it out and it works well. Best keep in mind any performance impact of this though, and as Daniel says, the ASP.NET implementations could change.
Based on my experience the Filter needs to be 'hooked' in the PreRequestHandlerExecute event at the latest to make it work in IIS version older than version 7.
I am having a hard time tracking down a lock issue, so I would like to log every method call's entry and exit. I've done this before with C++ without having to add code to every method. Is this possible with C#?
Probably your best bet would be to use an AOP (aspect oriented programming) framework to automatically call tracing code before and after a method execution. A popular choice for AOP and .NET is PostSharp.
If your primary goal is to log function entry/exit points and occasional information in between, I've had good results with an Disposable logging object where the constructor traces the function entry, and Dispose() traces the exit. This allows calling code to simply wrap each method's code inside a single using statement. Methods are also provided for arbitrary logs in between. Here is a complete C# ETW event tracing class along with a function entry/exit wrapper:
using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace MyExample
{
// This class traces function entry/exit
// Constructor is used to automatically log function entry.
// Dispose is used to automatically log function exit.
// use "using(FnTraceWrap x = new FnTraceWrap()){ function code }" pattern for function entry/exit tracing
public class FnTraceWrap : IDisposable
{
string methodName;
string className;
private bool _disposed = false;
public FnTraceWrap()
{
StackFrame frame;
MethodBase method;
frame = new StackFrame(1);
method = frame.GetMethod();
this.methodName = method.Name;
this.className = method.DeclaringType.Name;
MyEventSourceClass.Log.TraceEnter(this.className, this.methodName);
}
public void TraceMessage(string format, params object[] args)
{
string message = String.Format(format, args);
MyEventSourceClass.Log.TraceMessage(message);
}
public void Dispose()
{
if (!this._disposed)
{
this._disposed = true;
MyEventSourceClass.Log.TraceExit(this.className, this.methodName);
}
}
}
[EventSource(Name = "MyEventSource")]
sealed class MyEventSourceClass : EventSource
{
// Global singleton instance
public static MyEventSourceClass Log = new MyEventSourceClass();
private MyEventSourceClass()
{
}
[Event(1, Opcode = EventOpcode.Info, Level = EventLevel.Informational)]
public void TraceMessage(string message)
{
WriteEvent(1, message);
}
[Event(2, Message = "{0}({1}) - {2}: {3}", Opcode = EventOpcode.Info, Level = EventLevel.Informational)]
public void TraceCodeLine([CallerFilePath] string filePath = "",
[CallerLineNumber] int line = 0,
[CallerMemberName] string memberName = "", string message = "")
{
WriteEvent(2, filePath, line, memberName, message);
}
// Function-level entry and exit tracing
[Event(3, Message = "Entering {0}.{1}", Opcode = EventOpcode.Start, Level = EventLevel.Informational)]
public void TraceEnter(string className, string methodName)
{
WriteEvent(3, className, methodName);
}
[Event(4, Message = "Exiting {0}.{1}", Opcode = EventOpcode.Stop, Level = EventLevel.Informational)]
public void TraceExit(string className, string methodName)
{
WriteEvent(4, className, methodName);
}
}
}
Code that uses it will look something like this:
public void DoWork(string foo)
{
using (FnTraceWrap fnTrace = new FnTraceWrap())
{
fnTrace.TraceMessage("Doing work on {0}.", foo);
/*
code ...
*/
}
}
A profiler is great for looking at your running code during development but if you're looking for the ability to do custom traces in production, then, as Denis G. mentionned, PostSharp is the perfect tool: you don't have to change all your code and you can easily switch it on/off.
It's also easy to set-up in a few minutes and Gaƫl Fraiteur, the creator of PostSharp even has videos that shows you how easy it is to add tracing to an existing app.
You will find examples and tutorials in the documentation section.
Use ANTS Profiler from Red Gate would be your best bet. Failing that, look into interceptors in Castle Windsor. That does assume you're loading your types via IoC though.
Reflection is another way, you can use the System.Reflection.Emit methods to "write" code into memory. That code could replace your method's code, and execute it but with appropriate logging. Good luck on that one, though... Easier would be to use an Aspect Oriented Programming framework like Aspect#.
It might be waiting for the lock issue to take hold, doing a memory dump and analysing the call stack on various threads. You can use DebugDiag or the adplus script (hang mode, in this case) that comes with Debugging Tools for Windows.
Tess Ferrandez also has an excellent lab series on learning to debug various issues using .NET memory dumps. I highly recommend it.
How do you know that it's happening? If this is a multithreaded application, i would recommend testing for the condition and calling System.Diagnostics.Debugger.Break() at runtime when it's detected. Then, simply open up the Threads window and step through the call stacks on each relevant thread.