My goal is to save in a file the callstack state when an exception is raised. But I have one major restraint: I cannot touch any of the existing code. My goal is to implement that in a context where I'm unaware of the current workflow. So I can use it in any C# Project.
To do so I need to have access to all the nested methods that lead to the exception but also all the method's arguments.
Until now I used postsharp OnMethodBoundaryAspect which allow me to define OnEntry, OnSucess, and OnException method that is called whenever a method: is entered, returns, or raise an exception. What is great is that I can apply this aspect with a postsharp.config
file in the project I want. No source modification, I'm only adding my project to the solution, a config file, and reference to my project in every project of the solution and I'm good to go. Using that I could maintain a callstack of my own, and I could save references to methods' name, and ref to methods' arguments.
Now let's say a methodA
calls a methodB
which calls a methodC
.
What I've done works well except that obviously I use references. So if methodA
argument is modified in methodC
just before raising an exception, when I serialize the call stack, We'll see a call stack where methodA
has an argument with a wrong value (we'll see the value set in methodC
).
I want to fix this issue and I considered using:
- deepcloning in the OnEntry method to copy all the methods parameters but that would lead to awful performances
- PostSharp LocationInterceptorAspect but that requires a paid licence
- VEH Hooking but it is incredibly slow and it would probably be faster to use
deepcloning
Is there any other way that would allow me to save the state of an object in time with greater performances than deepcloning
, or at least let me intercept all modifications brought to a specified object (like the VEH hooking or the LocationInterceptor Aspect)?
PS: I can't use IOnPropertyChange
or things like that because I can't touch any of the existing sourceCode except if I can implement them at runtime but I didn't see anywhere that it was possible.