问题
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.
回答1:
Considering that I didn't want to implement any specific code in the object that needed to be monitered I had only 2 options :
Serialization or any deepcloning method whenever a state need to be saved (I used JSON.NET for this solution)
Logging all modification brought to the object in order to reverse them if necessary => to be notified when a modification will occur I explored all ths techniques:
- Postsharp with the LocationInterceptionAspect (not free)
- Harmony 2 which allow to intercept any function call (and in my case the setter function of properties), simplest and easiest working solution if you can discard any field changes
- VEH hooking, would work in theory but extremely slow and I didn't explore it that much because of its complexity
- Editing the MSIL code of a function to hook all the
stfld
instruction.
来源:https://stackoverflow.com/questions/64750335/how-can-i-keep-a-ref-to-an-objects-state-at-a-given-time